Discourse is the modern open-source forum: threaded discussions with infinite scroll, real-time updates, trust levels that reduce moderation work, mobile-friendly design and a large plugin ecosystem. It’s used for product communities, support forums and open-source projects. The official way to self-host it is the discourse_docker launcher, which builds and manages a single container for you.

Requirements

  • 2 GB RAM minimum (with 2 GB swap). 4 GB is recommended for comfortable use and rebuilds. 2 vCPU.
  • 20+ GB disk, more for uploads (or use S3-compatible storage).
  • A domain or subdomain, e.g. forum.example.com, pointing to the server.
  • Working SMTP, which is essential. Discourse can’t activate accounts without email. See transactional email services.
  • Ports 80 and 443 free (the container handles HTTPS itself by default).

1. Install Docker and clone the launcher

sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers

The setup script installs Docker if it’s missing.

2. Run the setup

./discourse-setup

It asks for:

  • the hostname (forum.example.com);
  • admin email addresses;
  • SMTP server, port, username and password;
  • an email address for Let’s Encrypt.

The script checks DNS and ports, writes containers/app.yml, and bootstraps the container. That takes several minutes. Then open https://forum.example.com and register with one of the admin emails to activate the admin account.

3. Configure the site

The setup wizard guides you through the name, logo, privacy (public, or login required), and categories. Important settings afterwards:

  • Login: enable social logins or SSO (OAuth, OIDC, DiscourseConnect) if needed;
  • Trust levels and moderation: review defaults, and add moderators;
  • Spam protection: Akismet plugin, approval for new users’ first posts.

Plugins

Plugins are added 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

Then rebuild:

cd /var/discourse && ./launcher rebuild app

A rebuild takes a few minutes of downtime.

Running behind your own Nginx

If the server hosts other sites, let Nginx handle 80/443, and run Discourse on a socket or local port. In app.yml, remove the SSL templates, add the web.socketed.template.yml template, and remove the exposed ports. Then proxy from Nginx:

server {
    server_name forum.example.com;
    client_max_body_size 50M;
    location / {
        proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
    # listen 443 ssl; certbot --nginx -d forum.example.com
}

See Nginx server blocks.

Backups

Discourse has built-in backups (Admin → Backups): database plus uploads, on a schedule. Configure them to upload to S3-compatible storage, so copies live off the server. Test a restore occasionally:

cd /var/discourse && ./launcher enter app
discourse restore <backup-file.tar.gz>

See backup strategy.

Upgrades

Minor updates run from Admin → Upgrade (via docker_manager). Bigger ones need a rebuild:

cd /var/discourse
git pull
./launcher rebuild app

Rebuild regularly to pick up security fixes. See updating self-hosted apps.

Troubleshooting

./launcher logs app
./discourse-doctor        # checks DNS, email, memory and common problems
  • No activation emails: check SMTP settings in app.yml, SPF/DKIM for the sender domain, and provider logs. See email deliverability.
  • Out of memory during rebuild: add swap. See swap.
  • Let’s Encrypt fails: DNS must point to the server, and port 80 must be reachable.

Quick reference

Task Command
Setup ./discourse-setup
Rebuild (after config or plugin changes) ./launcher rebuild app
Logs ./launcher logs app
Shell inside ./launcher enter app
Diagnose ./discourse-doctor
Config containers/app.yml

Related: Mastodon and Docker security.

  • Self-Hosting
  • Community
  • Docker