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)
RequirementMinimumRecommended
CPU2 cores4 cores
RAM2 GB4 GB
Disk20 GB40 GB+
EmailSMTP requiredTransactional 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

  1. Navigate to http://forum.example.com in your browser
  2. You’ll see the setup wizard — create your admin account using the email you specified in DISCOURSE_DEVELOPER_EMAILS
  3. Check your email for the activation link (this confirms SMTP is working)
  4. 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

ResourceIdleActive Community (100+ DAU)
RAM~800 MB2-4 GB
CPULowMedium-High
Disk10 GB base20-100 GB (grows with uploads)
BandwidthMinimal50-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.

Comments