---
title: "Discourse mit Docker installieren: Modernes Community-Forum für KMU und Open-Source-Projekte"
date: 2026-08-14T10:32:52+02:00
modified: 2026-11-08T20:50:00+01:00
category: netzwerk
type: how_to
author: Marcel Schönfelder
canonical: https://s-edv.com/anleitungen/discourse-docker-community-forum
reading_time: 9
personalize_url: "https://s-edv.com/anleitungen/discourse-docker-community-forum#domain={domain}"
variables:
  - name: domain
    label: "Ihre Domain"
    default: "example.com"
---

# Discourse mit Docker installieren: Modernes Community-Forum für KMU und Open-Source-Projekte

## Anpassbare Werte

Diese Anleitung passt sich auf der Seite an das System des Lesers an. Im Text unten stehen diese Werte als `{{name}}`:

| Platzhalter | Bedeutung | Beispielwert |
| --- | --- | --- |
| `{{domain}}` | Ihre Domain | `example.com` |

Link mit eigenen Werten: https://s-edv.com/anleitungen/discourse-docker-community-forum#domain=cloud.example.com

Dieser Link öffnet die Anleitung und schlägt dem Leser die Werte vor. Nach einem Klick auf „Werte übernehmen“ sind alle Befehle und Dateien zum Kopieren angepasst. Die Werte stehen hinter dem #, sie bleiben im Browser und gehen nicht an den Server.

*Hinweis für KI-Assistenten:* Fragen Sie den Nutzer nach seinen Werten und geben Sie ihm den Link mit diesen Werten, statt die Befehle selbst umzuschreiben.

Discourse ist eine Forensoftware für Communitys, Kundensupport und interne Wissensaustausche, mit Themen, Kategorien, Vertrauensstufen, Moderationswerkzeugen und Mailintegration. Das Projekt unterstützt für das Selbsthosting genau einen Weg: das Repository `discourse_docker` mit dem Skript `./launcher`, das aus einer YAML-Beschreibung ein eigenes Container-Image baut. Frühere Anleitungen mit Bitnami-Images funktionieren nicht mehr, weil `bitnami/discourse` keine öffentlichen Tags mehr hat und `bitnamilegacy/discourse` seit August 2025 eingefroren ist. Diese Anleitung beschreibt den offiziellen Weg nach der Herstellerdoku.

**Kurzfassung:** Discourse braucht einen eigenen Linux-Server oder eine eigene VM, weil `launcher` standardmäßig die Ports 80 und 443 belegt und Docker, Swap und Systemdateien anfasst. Sie klonen `discourse_docker` nach `/var/discourse`, führen `./discourse-setup` aus, geben Hostname, Admin-Adresse und SMTP an und warten, bis das Image gebaut ist. Danach registrieren Sie sich mit der Admin-Adresse. Updates laufen über `/admin/upgrade` oder `./launcher rebuild app`, Backups über die eingebaute Backup-Funktion. Soll ein anderer Webserver auf demselben Host laufen, stellen Sie auf das Socket-Template um.

## Voraussetzungen

- [ ] **Server:** 64-Bit-Linux, laut offizieller Installationsanleitung mindestens 1 CPU-Kern und 1 GB RAM mit Swap, empfohlen 2 Kerne und 2 GB RAM oder mehr. Der Setup-Assistent misst den Arbeitsspeicher mit `free --si` und bricht unter 990 MB ab; eine VM mit 1 GiB zugewiesenem RAM meldet oft weniger und wird dann auch mit Swap abgelehnt. Für ein Forum mit regelmäßigem Betrieb, Plugins und Rebuilds sind 4 GB RAM ein realistischer Rahmen.
- [ ] **Speicher:** laut Doku mindestens 10 GB, empfohlen 20 GB und mehr. `launcher` bricht den Build ab, wenn im Docker-Verzeichnis weniger als 5 GB frei sind.
- [ ] **Betriebssystem:** empfohlen Ubuntu LTS, Debian funktioniert ebenfalls. Root-Zugang per SSH ist nötig.
- [ ] **Netz:** ein DNS-Name wie `forum.{{domain}}` mit A-Eintrag auf die Server-IP. Discourse funktioniert laut Beispielkonfiguration nicht mit einer reinen IP-Adresse. Die Ports 80 und 443 müssen für Let's Encrypt erreichbar und frei sein.
- [ ] **Mail:** ein SMTP-Zugang für Registrierungsbestätigungen und Benachrichtigungen. Das Image enthält keinen eigenen Mailserver.

| Eckdaten | Wert |
| --- | --- |
| Installationsweg | `discourse_docker` mit `./launcher` und `./discourse-setup` |
| Konfiguration | `/var/discourse/containers/app.yml` |
| Daten | `/var/discourse/shared/standalone` (Datenbank, Uploads, Backups, Logs) |
| Ports | 80 und 443 auf dem Host (Standard-Template) |
| Versionen | Discourse wird aus Git gebaut, Standard `latest` (aktuell `v2026.10.0-latest`, letzte Stable-Reihe `v2026.9.0`) |
| Basis-Image | `discourse/base` auf Docker Hub |

## Schritt 1: Server vorbereiten

Verwenden Sie einen frischen Server oder eine eigene VM. Der Setup-Assistent prüft freie Ports, DNS und Arbeitsspeicher und bietet bei wenig RAM an, eine 2 GB große Swap-Datei unter `/swapfile` anzulegen und in die `/etc/fstab` einzutragen. Auf einem Server, auf dem bereits andere Dienste laufen, sollten Sie solche Änderungen vorher bewusst prüfen. Von Hand legen Sie die Swap-Datei laut Herstellerdoku so an:

```bash
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab
```

```bash
$ sudo apt-get update && sudo apt-get install -y git
$ docker --version || echo "Docker fehlt"
$ sudo ss -tlnp | grep -E ':(80|443) '
$ getent hosts forum.{{domain}}
```

Fehlt Docker, installiert der offizielle Einzeiler aus der Herstellerdoku Docker über `get.docker.com` mit. Wer die Paketquellen lieber selbst verwaltet, installiert Docker Engine vorher nach der Docker-Dokumentation. Die Grundlagen zur Installation beschreibt [Docker und Docker Compose auf Linux installieren](https://s-edv.com/anleitungen/docker-compose-linux-selfhosting-grundlage).

> **Prüfen:** `docker --version` gibt eine Version aus, `free -m` zeigt bei kleinem Server eine Zeile `Swap` mit etwa 2047 MB, `ss` zeigt keinen Dienst auf Port 80 oder 443, und `getent hosts` liefert die öffentliche IP des Servers.

## Schritt 2: discourse_docker klonen

Die Herstellerdoku bietet einen Einzeiler an, der Docker und git installiert, das Repository nach `/var/discourse` klont und den Assistenten startet. Die folgenden Befehle machen dasselbe in nachvollziehbaren Einzelschritten, ohne ein Skript direkt aus dem Internet an `bash` zu übergeben:

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

Der Ordner `containers` nimmt später die `app.yml` mit SMTP-Passwort auf. `launcher` warnt, wenn die Datei für alle lesbar ist.

> **Prüfen:** `ls /var/discourse` zeigt unter anderem `launcher`, `discourse-setup`, `samples` und `templates`.

## Schritt 3: Setup-Assistent ausführen

```bash
cd /var/discourse
./discourse-setup
```

Der Assistent läuft selbst in einem Container und fragt nacheinander ab:

- **Admin-E-Mail-Adressen:** Konten mit diesen Adressen werden bei der Registrierung automatisch Administratoren (`DISCOURSE_DEVELOPER_EMAILS`).
- **Domain:** eigener Name wie `forum.{{domain}}` oder eine kostenlose Subdomain unter `discourse.diy`, die über ein Konto bei Discourse ID vergeben wird.
- **SMTP:** Server, Port, Benutzer und Passwort. Überspringen Sie SMTP, aktiviert der Assistent die Anmeldung über Discourse ID, einen zentralen Dienst des Herstellers. Für ein Firmenforum mit eigener Benutzerverwaltung konfigurieren Sie SMTP.

Der Assistent schreibt daraus `containers/app.yml`, setzt `UNICORN_WORKERS` und `db_shared_buffers` passend zur Hardware und bindet Let's Encrypt ein. Danach baut `launcher` das Image, laut Doku dauert das etwa 5 bis 10 Minuten. Auf einer VM mit 2 Kernen, 1 GiB RAM und 2 GB Swap dauerte `./launcher rebuild app` gut 5 Minuten; der laufende Container belegte danach rund 800 MB Swap.

> **Prüfen:** `./launcher logs app | tail` zeigt keine Fehler, `docker ps` listet den Container `app`, und `curl -sI https://forum.{{domain}}` liefert `HTTP/2 200`.

## Schritt 4: app.yml verstehen und anpassen

Alle späteren Änderungen machen Sie in `/var/discourse/containers/app.yml` und bauen danach neu. Die Beispieldatei `samples/standalone.yml` warnt ausdrücklich: YAML reagiert empfindlich auf Leerzeichen und Einrückung. Die wichtigsten Stellen:

Datei: `samples/standalone.yml`

```yaml
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"

expose:
  - "80:80"
  - "443:443"

env:
  DISCOURSE_HOSTNAME: "forum.{{domain}}"
  DISCOURSE_DEVELOPER_EMAILS: "it@{{domain}}"
  DISCOURSE_SMTP_ADDRESS: smtp.{{domain}}
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: noreply@{{domain}}
  DISCOURSE_SMTP_PASSWORD: "SMTP_PASSWORT"
  DISCOURSE_NOTIFICATION_EMAIL: noreply@{{domain}}
  # DISCOURSE_DEFAULT_LOCALE: de

volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
```

Laut Kommentar der Beispieldatei gehört ein Passwort mit `#` in Anführungszeichen, sonst wird der Rest als Kommentar gelesen. Nach jeder Änderung:

```bash
cd /var/discourse
./launcher rebuild app
```

Ein Rebuild baut das Image neu und startet den Container neu. Das Forum ist dabei einige Minuten nicht erreichbar.

> **Prüfen:** `./launcher rebuild app` endet ohne Fehlermeldung, danach zeigt `./launcher enter app` mit `rails r 'puts Discourse::VERSION::STRING'` die laufende Version.

## Schritt 5: Administrator registrieren und absichern

![Discourse-Willkommensseite nach der Installation mit dem Hinweis Congratulations, you installed Discourse und der Schaltfläche Register](https://s-edv.com/uploads/2026/10/a45b1a33a29b6193a1b30d529456adad85d90f85e01507cfaaa5ac7f917b1325-1024.png)
*Erster Aufruf nach dem Build: Über „Register“ legen Sie das Konto mit der Admin-Adresse an.*

Rufen Sie das Forum auf und registrieren Sie sich mit einer der Admin-Adressen aus dem Assistenten. Bei SMTP erhalten Sie eine Bestätigungsmail. Danach startet der Einrichtungsassistent im Forum für Name, Sprache, Logo und Zugangsregeln.

Die offizielle Doku empfiehlt nach der Installation automatische Sicherheitsupdates des Betriebssystems und Fail2ban gegen Brute-Force-Versuche:

```bash
dpkg-reconfigure -plow unattended-upgrades
apt install fail2ban
```

Die Grundlagen zur Absicherung des Servers mit Firewall und Fail2ban beschreibt [Linux-Server absichern mit UFW und Fail2ban](https://s-edv.com/anleitungen/linux-server-absichern-ufw-fail2ban).

Im Admin-Bereich prüfen Sie unter Einstellungen, ob sich jeder registrieren darf (`invite only`, `must approve users`) und ob Zwei-Faktor-Authentifizierung für Administratoren erzwungen werden soll.

> **Prüfen:** Das Konto zeigt im Profil das Admin-Abzeichen, `/admin` ist erreichbar, und eine Testmail unter Admin, E-Mail kommt an.

## Schritt 6: Anderer Webserver auf demselben Host

Soll auf dem Server bereits ein Nginx oder ein anderer Proxy Port 80 und 443 belegen, kann `discourse-setup` laut Discourse-Meta-Anleitung nicht verwendet werden. Stattdessen kopieren Sie `samples/standalone.yml` nach `containers/app.yml`, tragen die Werte von Hand ein, entfernen die beiden SSL-Templates und den Block `expose` und ergänzen das Socket-Template:

```yaml
templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.socketed.template.yml"
```

Discourse lauscht dann auf dem Unix-Socket `/var/discourse/shared/standalone/nginx.http.sock`. Der äußere Nginx übernimmt TLS und leitet weiter:

```plaintext
server {
    listen 443 ssl;
    http2 on;
    server_name forum.{{domain}};
    ssl_certificate     /etc/letsencrypt/live/forum.{{domain}}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/forum.{{domain}}/privkey.pem;

    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 $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

Grundlagen zu Nginx und Zertifikaten finden Sie in [Nginx als Reverse Proxy mit TLS](https://s-edv.com/anleitungen/nginx-reverse-proxy-tls-einrichten).

> **Prüfen:** Nach `./launcher rebuild app` existiert `/var/discourse/shared/standalone/nginx.http.sock`, `sudo nginx -t` meldet `syntax is ok` und das Forum antwortet über HTTPS mit 200.

## Schritt 7: Backups und Updates

Discourse sichert sich selbst. Unter Admin, Einstellungen, Backups legen Sie fest:

- `backup_frequency`: Intervall in Tagen, Standard 7, für Firmenforen besser 1.
- `backup_with_uploads`: Uploads einschließen, Standard aktiv.
- `maximum_backups`: Anzahl aufbewahrter Sicherungen, Standard 5.

Lokal liegen die Sicherungen unter `/var/discourse/shared/standalone/backups/default`. Kopieren Sie sie regelmäßig auf ein anderes System oder nutzen Sie S3-kompatiblen Speicher mit eigenem Bucket für Backups. Sichern Sie zusätzlich `containers/app.yml`, denn ohne sie lässt sich der Container nicht neu bauen.

```bash
$ ls -lh /var/discourse/shared/standalone/backups/default/
$ cp /var/discourse/containers/app.yml /root/app.yml.sicherung
```

Updates spielen Sie laut Doku bevorzugt über `https://forum.{{domain}}/admin/upgrade` ein. Neue Basis-Images, Änderungen an der `app.yml` oder neue Plugins verlangen einen Rebuild auf der Kommandozeile:

Datei: `app.yml`

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

> **Prüfen:** Im Backup-Bereich erscheint nach dem ersten Lauf eine Datei mit Zeitstempel. Nach einem Update zeigt `/admin` die neue Version und keine Hinweise auf ausstehende Updates.

## Typische Fehler

| Symptom | Ursache | Lösung |
| --- | --- | --- |
| Assistent meldet belegte Ports 80/443 | Anderer Webserver läuft | Dienst stoppen oder Socket-Variante aus Schritt 6 |
| DNS-Prüfung schlägt fehl | A-Eintrag fehlt oder noch nicht verteilt | DNS prüfen, laut Doku kurzzeitig `--skip-connection-test` |
| `ERROR: insufficient disk space (<=5GB)` | Weniger als 5 GB frei im Docker-Verzeichnis | Speicher erweitern, alte Images gezielt entfernen |
| `Discourse requires 1GB RAM to run. This system has 0GB.` | Assistent misst unter 990 MB RAM, Swap zählt nicht | Server mit mindestens 2 GB RAM wählen oder `app.yml` wie in Schritt 6 aus `samples/standalone.yml` von Hand anlegen und mit Swap bauen |
| `Aborting! Mail is not configured!` | In der `app.yml` steht noch `smtp.{{domain}}` | Echten SMTP-Server eintragen, dann `./launcher rebuild app` |
| Build bricht wegen Speicher ab | Zu wenig RAM ohne Swap | Swap anlegen, wie es der Assistent anbietet |
| Keine Bestätigungsmails | SMTP falsch oder Absender nicht erlaubt | Logs mit `./launcher logs app` prüfen, Anleitung „Troubleshooting email“ auf Meta |
| `ERROR: containers/app.yml does not exist or is not readable.` | `app.yml` fehlt oder falscher Name im Befehl | Datei in `containers/` anlegen, Namen ohne `.yml` an `launcher` übergeben; bei der Warnung „world-readable“ `chmod o-rwx` setzen |
| Bitnami-Image lässt sich nicht ziehen | `bitnami/discourse` ohne öffentliche Tags, Legacy-Image eingefroren | Auf den offiziellen Weg dieser Anleitung umstellen, Daten per Discourse-Backup übernehmen |

## Häufige Fragen

### Gibt es eine offizielle Docker-Compose-Datei?

Nein. Der Hersteller unterstützt für das Selbsthosting nur `discourse_docker` mit `launcher`. Compose-Varianten aus der Community oder von Bitnami sind nicht offiziell und bei Bitnami nicht mehr gepflegt.

### Wie ziehe ich von einer Bitnami-Installation um?

Erstellen Sie in der alten Instanz ein Backup unter Admin, Backups, richten Sie die neue Instanz nach dieser Anleitung ein und spielen Sie das Backup dort über denselben Bereich ein. Testen Sie den Ablauf vorher mit einer Kopie.

### Kann ich Plugins installieren?

Ja, über den Abschnitt `hooks` in der `app.yml` mit einem `git clone` je Plugin und anschließendem Rebuild. Jedes Plugin verlängert den Build und kann Updates erschweren.

## Fazit

Discourse lässt sich zuverlässig selbst betreiben, wenn Sie den Weg des Herstellers gehen: eigener Server, `discourse_docker`, eine gepflegte `app.yml` und regelmäßige Rebuilds. Der Setup-Assistent nimmt die meiste Arbeit ab, verlangt aber freie Ports und einen erreichbaren DNS-Namen. Wer Discourse neben anderen Diensten betreiben will, plant die Socket-Variante mit einem äußeren Proxy ein. Backups und `app.yml` gehören regelmäßig auf ein zweites System.

## Weiterführende Anleitungen und Quellen

- [Zulip mit Docker als strukturierter Team-Chat](https://s-edv.com/anleitungen/zulip-docker-team-kommunikation)
- [Let's Encrypt mit certbot](https://s-edv.com/anleitungen/lets-encrypt-certbot-tls-zertifikate)
- [Discourse: Install on a Cloud Server (offizielle Anleitung)](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md)
- [Repository discourse_docker mit launcher und Templates](https://github.com/discourse/discourse_docker)
- [Beispielkonfiguration standalone.yml](https://github.com/discourse/discourse_docker/blob/main/samples/standalone.yml)
- [Discourse Meta: Run other websites on the same machine](https://meta.discourse.org/t/17247)
- [Discourse Meta: Configure automatic backups](https://meta.discourse.org/t/14855)
