Discourse has exactly one supported installation path, Docker through the project's own launcher script, and accepting that constraint makes the deployment predictable. What catches people out is elsewhere: setup cannot complete without working outbound email, the documented 1 GB minimum is genuinely a minimum, and every change happens through a rebuild rather than by editing files in place.
That single supported path is a deliberate decision by the maintainers rather than an oversight. Discourse is a Rails application with PostgreSQL, Redis and Sidekiq behind it, and supporting every combination of distribution and package version those components can arrive in is work the project declined to take on. What you get in exchange is a deployment that behaves identically everywhere, and a support forum where the answers apply to your install.
MassiveGRID Ubuntu VPS: Ubuntu 24.04 LTS · Proxmox HA cluster with automatic failover · Ceph 3x replicated NVMe storage · independent CPU, RAM and storage scaling · 12 Tbps DDoS protection
Cloud VPS — from $1.99/mo
Dedicated VPS for consistent rebuild times · Fully managed hosting
What You Need Before Starting
Discourse will not finish its setup without working outbound email. This is not a recommendation, it is a hard requirement: the installer sends the administrator confirmation by email, and without it you cannot create the first account. Arrange an SMTP provider first, with credentials in hand.
Sending directly from the VPS is a poor idea for a forum in particular. Discourse generates a high volume of notification mail, and a new IP with no sending reputation gets filtered, which reads to your members as a broken site.
You also need a domain pointed at the server before installation, because the setup script requests a Let's Encrypt certificate for it.
Sizing
Discourse is a Rails application with PostgreSQL, Redis and Sidekiq behind it. That stack has a real memory floor.
| Community size | Configuration | MassiveGRID VPS |
|---|---|---|
| Small, under 100 active | 2 vCPU / 4 GB GB / 64 GB | $9.58/mo |
| Medium, a few hundred active | 2 vCPU / 8 GB GB / 128 GB | $13.42/mo |
| Busy, thousands of members | 4 vCPU / 8 GB GB / 256 GB | $20.44/mo |
| Large, or with heavy uploads | 8 vCPU / 16 GB GB / 256 GB+ | $38.32/mo |
The project documents 1 GB as a minimum with swap, and that figure is genuinely a minimum: it will install and it will be slow, and a rebuild may fail. Start at 4 GB. Swap is worth adding regardless, because the asset compilation step during a rebuild is the memory peak and it is transient.
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Installation
Install Docker first, covered in our Docker installation guide, then clone the Discourse Docker repository and run the setup script:
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers
./discourse-setup
The script asks for the hostname, administrator email addresses, SMTP details and optionally a Let's Encrypt contact address, writes containers/app.yml, then builds and starts the container. The build takes a while on a small server; it is compiling assets, not hanging.
Everything afterwards flows through the launcher rather than through Docker commands directly:
./launcher logs app
./launcher restart app
./launcher rebuild app
./launcher enter app
The Rebuild Model
This is the mental adjustment Discourse requires. You do not edit files inside the container and you do not upgrade packages in place. You edit containers/app.yml and run a rebuild, which constructs a fresh container from the current template and your configuration.
The consequence is that any change made inside the container is lost at the next rebuild. It also means the configuration file is the complete description of the deployment, which makes it the single most important thing to back up and version.
Rebuilds cause a few minutes of downtime and are the operation most likely to fail on an undersized server, because asset compilation is memory-hungry. Rebuild deliberately, during a quiet period, not casually.
Settings Worth Changing in app.yml
env:
LANG: en_US.UTF-8
DISCOURSE_HOSTNAME: forum.example.com
DISCOURSE_DEVELOPER_EMAILS: 'you@example.com'
DISCOURSE_SMTP_ADDRESS: smtp.provider.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: apikey
DISCOURSE_SMTP_PASSWORD: "your-key"
DISCOURSE_SMTP_ENFORCE_TLS: true
DISCOURSE_NOTIFICATION_EMAIL: noreply@example.com
UNICORN_WORKERS: 4
db_shared_buffers: "1024MB"
UNICORN_WORKERS sets the web worker count. The setup script picks a value from detected memory, which is usually sensible; raise it only if you have RAM to spare, since each worker is a full Rails process.
db_shared_buffers is PostgreSQL's cache inside the container, and the default is conservative. Roughly a quarter of total RAM is a reasonable target, and on a forum it produces a noticeable improvement because the working set is small and cacheable.
After editing, apply it:
./launcher rebuild app
Backups
Discourse has a built-in backup system, and it is one of the better ones. Enable it in the admin settings under Backups, set a schedule and a retention count, and it produces an archive containing the database and, if you enable the option, the uploaded files.
That last option is the one to check. The default in some configurations excludes uploads, which produces a backup that restores every post with broken images. Turn on including uploads unless you have a specific reason not to.
Backups land inside the container's shared volume, on the same server, which is not a backup. Copy them off:
rsync -az --remove-source-files \
/var/discourse/shared/standalone/backups/default/ \
backup-host:/archive/discourse/
# and keep the deployment description itself
cp /var/discourse/containers/app.yml /archive/discourse/app.yml
Configure the S3 backup target instead if you have object storage, which removes the copy step. Our MinIO guide covers running that endpoint yourself.
Uploads and the CDN Question
Attachments and images grow faster than the database on any active forum. Two options: keep them on the server and grow the disk, or move them to S3-compatible storage with DISCOURSE_S3_* settings.
Object storage is the better answer for a large community, and it introduces one trap: migrating existing uploads to S3 after the fact is a rake task that must complete, and interrupting it leaves posts referencing both locations. Decide before the forum has years of content.
A CDN is optional and helps most for an image-heavy community with a geographically spread membership. Set DISCOURSE_CDN_URL and Discourse rewrites asset and upload URLs accordingly.
Moderation Is the Real Cost
The infrastructure is roughly ten dollars a month and an afternoon. Running a forum is neither.
Discourse ships strong tools, trust levels that grant permissions as members participate, flagging that routes to moderators, rate limits on new accounts, and Akismet integration for spam. They reduce the work; they do not remove it. A public forum with open registration attracts spam registrations continuously, and an unmoderated community degrades in a way no configuration prevents.
Plan for who moderates before launching. This is the most common reason self-hosted forums are abandoned, and it has nothing to do with the server.
Infrastructure for a Community Archive
A forum's value is cumulative. Years of questions, answers and decisions accumulate into something genuinely irreplaceable, and unlike code it exists in exactly one place.
Every MassiveGRID VPS runs on a Proxmox high-availability cluster with automatic failover, so a hardware fault migrates the container rather than ending it. Storage is Ceph with three-way replication across independent NVMe drives, which is the durability a community archive deserves. Independent scaling matters here in particular, because uploads grow the disk long before the forum needs more CPU.
Given that rebuilds are the memory-hungry operation, a Dedicated VPS with guaranteed cores makes them predictable rather than occasionally failing under contention. Cloud VPS plans start at $1.99/mo, and our sizing guide compares requirements across applications.