How to Self-Host Discourse with Docker
What Is Discourse?
Discourse is the most popular open-source forum platform on the internet. Built by Jeff Atwood (co-founder of Stack Overflow), it powers communities for companies like GitHub, Docker, and Netlify. It replaces legacy forum software like phpBB, vBulletin, and Vanilla Forums with a modern, real-time discussion experience. Official site
Unlike most self-hosted apps covered on this site, Discourse uses its own Docker-based launcher rather than a standard Docker Compose workflow. This is intentional — the launcher handles database migrations, plugin installation, and container rebuilds in a way that a plain Compose file can’t. It’s unconventional but battle-tested across thousands of production instances.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended) with dedicated IP
- Docker installed (guide)
- 2 GB RAM minimum (4 GB recommended for active communities)
- 20 GB of free disk space
- A domain name pointing to your server
- Working SMTP credentials (Discourse requires email for account verification)
| Requirement | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4 cores |
| RAM | 2 GB | 4 GB |
| Disk | 20 GB | 40 GB+ |
| SMTP required | Transactional email service |
Installation
Discourse’s official install method uses discourse_docker, their custom launcher. Clone the repository and run the setup script:
sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers
Configuration
Create your app configuration file at containers/app.yml. This is the equivalent of a Docker Compose file for Discourse:
## Discourse Single-Container App Configuration
## /var/discourse/containers/app.yml
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## Uncomment for SSL via Let's Encrypt:
# - "templates/web.ssl.template.yml"
# - "templates/web.letsencrypt.ssl.template.yml"
## Exposed ports
expose:
- "80:80" # HTTP
- "443:443" # HTTPS (uncomment SSL templates above)
params:
db_default_text_search_config: "pg_catalog.english"
## Set database shared buffers (25% of RAM recommended)
db_shared_buffers: "512MB"
## UNICODE encoding required
db_work_mem: "40MB"
env:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LANGUAGE: en_US.UTF-8
## REQUIRED — your forum's hostname
DISCOURSE_HOSTNAME: forum.example.com
## REQUIRED — first admin account email
DISCOURSE_DEVELOPER_EMAILS: '[email protected]'
## REQUIRED — SMTP configuration (Discourse will NOT work without email)
DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: [email protected]
DISCOURSE_SMTP_PASSWORD: your-smtp-password
DISCOURSE_SMTP_ENABLE_START_TLS: true
DISCOURSE_SMTP_DOMAIN: forum.example.com
DISCOURSE_NOTIFICATION_EMAIL: [email protected]
## Optional — CDN and performance
# DISCOURSE_CDN_URL: https://cdn.example.com
volumes:
- volume:
host: /var/discourse/shared/standalone
guest: /shared
- volume:
host: /var/discourse/shared/standalone/log/var-log
guest: /var/log
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
run:
- exec: echo "Beginning Discourse bootstrap"
Build and Launch
cd /var/discourse
./launcher bootstrap app
./launcher start app
The bootstrap process takes 5-10 minutes. It builds the Docker image, sets up PostgreSQL and Redis inside the container, runs database migrations, and compiles assets.
Initial Setup
- Navigate to
http://forum.example.comin your browser - You’ll see the setup wizard — create your admin account using the email you specified in
DISCOURSE_DEVELOPER_EMAILS - Check your email for the activation link (this confirms SMTP is working)
- Walk through the wizard: site name, description, default categories, and logo upload
Default admin creation: If you miss the wizard, create an admin from the command line:
cd /var/discourse
./launcher enter app
rake admin:create
Configuration
Key Settings (Admin Panel)
Access settings at /admin/site_settings:
- Required Fields: Site name, site description, contact email
- User Registration:
login_required(private forum),must_approve_users,invite_only - Content:
min_post_length,min_topic_title_length,max_image_size_kb - Email:
email_in(reply via email),disable_digest_emails - Security:
force_https,allowed_iframes,content_security_policy
Plugin Installation
Add plugins in containers/app.yml under the hooks section:
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
- git clone https://github.com/discourse/discourse-solved.git
- git clone https://github.com/discourse/discourse-voting.git
- git clone https://github.com/discourse/discourse-assign.git
After adding plugins, rebuild:
./launcher rebuild app
Advanced Configuration
Multi-Container Setup (High Traffic)
For forums expecting heavy traffic, split services across containers:
## containers/data.yml — PostgreSQL + Redis
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
## containers/web_only.yml — Web server only
templates:
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
env:
DISCOURSE_DB_HOST: data
DISCOURSE_REDIS_HOST: data
SSL with Let’s Encrypt
Uncomment the SSL templates in app.yml:
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
- "templates/web.ssl.template.yml"
- "templates/web.letsencrypt.ssl.template.yml"
env:
LETSENCRYPT_ACCOUNT_EMAIL: [email protected]
SSO / OAuth Integration
Discourse supports external authentication via OAuth2, SAML, and OpenID Connect. Enable in site settings under Login:
- Google OAuth2
- GitHub OAuth
- Discord OAuth
- Custom OAuth2 provider
- SAML 2.0 (via plugin)
Reverse Proxy
If running Discourse behind an existing reverse proxy (Nginx Proxy Manager, Traefik, Caddy), expose only port 80 and set the X-Forwarded-Proto header. In app.yml:
expose:
- "127.0.0.1:4080:80"
env:
DISCOURSE_FORCE_HTTPS: true
Caddy example:
forum.example.com {
reverse_proxy localhost:4080
}
For more proxy options, see our Reverse Proxy Setup guide.
Backup
Discourse has built-in backup functionality accessible at /admin/backups:
- Automatic backups: Enabled by default, runs daily
- Backup location:
/var/discourse/shared/standalone/backups/ - Includes: Database, uploads, site settings
Manual backup from command line:
cd /var/discourse
./launcher enter app
discourse backup
Copy backups off-server for safety. See our Backup Strategy guide for a comprehensive approach.
Troubleshooting
Emails Not Sending
Symptom: Users can’t register, no activation emails received.
Fix: SMTP is required. Verify your SMTP credentials in app.yml. Test with:
./launcher enter app
rails runner "Email::Sender.new(UserNotifications.signup(User.last), :signup).send"
Common issue: using Gmail SMTP — Google blocks “less secure apps.” Use a transactional email service like Mailgun, SendGrid, or Amazon SES instead.
Bootstrap Fails with Memory Error
Symptom: ./launcher bootstrap app crashes or OOM-kills.
Fix: Discourse needs at least 2 GB RAM. If your server has only 1 GB, add swap:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Container Won’t Start After Update
Symptom: ./launcher start app fails after a system update.
Fix: Rebuild the container:
cd /var/discourse
git pull
./launcher rebuild app
Slow Performance
Symptom: Pages load slowly, high CPU usage.
Fix: Check db_shared_buffers in app.yml — set to 25% of available RAM. Enable CDN for static assets. Check for misbehaving plugins by disabling them one at a time in safe mode (/safe-mode).
Sidekiq Jobs Stuck
Symptom: Emails delayed, search not updating, digest emails not sent.
Fix: Check Sidekiq at /sidekiq. Restart Sidekiq:
./launcher enter app
sv restart sidekiq
Resource Requirements
| Resource | Idle | Active Community (100+ DAU) |
|---|---|---|
| RAM | ~800 MB | 2-4 GB |
| CPU | Low | Medium-High |
| Disk | 10 GB base | 20-100 GB (grows with uploads) |
| Bandwidth | Minimal | 50-200 GB/month |
Discourse is one of the heavier self-hosted applications. A $10-20/month VPS handles small communities. Active forums with thousands of users need 4+ GB RAM and dedicated CPU.
Verdict
Discourse is the best self-hosted forum software, period. Nothing else comes close in terms of features, polish, mobile experience, and community size. The custom Docker launcher is initially confusing if you’re used to Docker Compose, but it actually simplifies operations once you understand it.
Choose Discourse if you’re building a serious community forum with moderation needs, rich content, and long-form discussions. It’s the forum software that companies like GitHub, Docker, and Cloudflare trust for their own communities.
Look elsewhere if you need a lightweight, simple forum. Discourse requires 2+ GB RAM and working SMTP — it’s overkill for a small hobby project. Consider Flarum for something lighter.
FAQ
Can I migrate from phpBB/vBulletin to Discourse?
Yes. Discourse has built-in importers for phpBB, vBulletin, Vanilla, SMF, and many other forum platforms. Run them via the command line inside the container. Migration preserves users, posts, categories, and most metadata.
Does Discourse support real-time chat?
Yes. Discourse Chat is a built-in feature (since 2022) that provides Slack-like channels alongside traditional forum threads. Enable it in site settings.
How do I update Discourse?
From the web admin panel at /admin/upgrade or via command line: cd /var/discourse && ./launcher rebuild app. The web updater handles most updates; the command line is needed for major version jumps.
Can Discourse handle 100,000+ users?
Yes. Discourse scales well with proper hardware. The multi-container setup separates the database from the web server. Large forums run on 8+ GB RAM with PostgreSQL tuning. Discourse.org itself runs Discourse.
Is Discourse free?
The software is 100% open source (GPL v2). Self-hosting is free. Discourse also offers paid hosting starting at $50/month if you don’t want to manage the server yourself.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments