Anleitung: Discourse mit Traefik 3.0 und Docker einrichten

:rocket: Discourse Installation 2025: Docker, Traefik & Security-Stack

– Die ultimative Anleitung für Ubuntu 22.04+ mit CrowdSec & Authelia –

Du willst Discourse nicht einfach nur „installieren“, sondern sicher und performant hinter einem modernen Reverse-Proxy betreiben? Diese Anleitung führt dich durch ein Production-Ready Setup.

Wir nutzen das offizielle Docker-Image, koppeln es aber mit Traefik (für SSL/Routing), CrowdSec (für Intrusion Prevention) und passen die PostgreSQL-Performance manuell an.


:brain: Die Architektur

Bevor wir tippen, verstehen wir den Flow. Anders als bei Standard-Installationen übernimmt Traefik hier das HTTPS-Termination und leitet den Traffic gefiltert weiter.

DiscourseArchitecture Internet 🌍 Internet Traefik 🛡️ Traefik Proxy (Ports 80/443) + CrowdSec Bouncer Internet->Traefik HTTPS Discourse 💬 Discourse App (Docker Container) Traefik->Discourse HTTP (Intern) Postgres 🗄️ PostgreSQL (Datenbank) Discourse->Postgres Persistenz Redis ⚡ Redis (Cache/Queue) Discourse->Redis Jobs

:white_check_mark: Voraussetzungen & Checkliste

Stelle sicher, dass deine Umgebung bereit ist. Fehler hier kosten später Stunden!

  • OS: Ubuntu 22.04 LTS (oder neuer).
  • Hardware: Min. 2 vCPU / 2 GB RAM (Empfehlung: 4 GB RAM für die Konfig unten).
  • Storage: Min. 20 GB freier Speicher (für Docker Volumes & Backups).
  • Netzwerk:
    • Ports 80/443 sind frei (kein Apache/Nginx vorinstalliert!).
    • Docker-Netzwerke proxy und crowdsec existieren.
  • DNS: example.com zeigt per A-Record auf deine Server-IP.
  • Mail: Funktionierende SMTP-Daten (z. B. via SendGrid, Mailgun oder eigenem Server).

:warning: Kritisch: Traefik muss bereits laufen und korrekt konfiguriert sein (inkl. acme.json für Let’s Encrypt), da wir uns auf dessen Netzwerke und Middlewares verlassen.


:hammer_and_wrench: Schritt 1: Vorbereitung des Dateisystems

Wir klonen nicht nur das Repo, sondern setzen strikte Berechtigungen, um Probleme mit dem Postgres-Container zu vermeiden.

Führe folgende Befehle als root (oder mit sudo) aus:

# 1. Verzeichnis erstellen & Repo klonen
cd /opt/containers
mkdir -p discourse
cd discourse
git clone [https://github.com/discourse/discourse_docker.git](https://github.com/discourse/discourse_docker.git)
cd discourse_docker

# 2. Setup-Skript erstellen
nano setup.sh

Füge diesen Inhalt in die setup.sh ein. Er sorgt dafür, dass die Volumes auf dem Host existieren und Docker darauf zugreifen darf:

📄 Inhalt von setup.sh anzeigen
#!/bin/bash
# Erstellt Ordnerstruktur für persistente Daten
mkdir -p /var/discourse/shared/standalone/{backups/default,postgres_data,log/var-log}

# Setzt Rechte: root:docker (damit der Daemon schreiben kann)
chown -R root:docker /var/discourse/shared/standalone
chmod -R 755 /var/discourse/shared/standalone

echo "✅ Ordnerstruktur und Berechtigungen gesetzt."

Ausführen:

chmod +x setup.sh
./setup.sh

:gear: Schritt 2: Die app.yml Konfiguration

Das ist das Herzstück. Wir nutzen keine Ports (expose), sondern Labels für Traefik.

:light_bulb: Performance-Tipp: In der Konfig unten steht db_shared_buffers: "4096MB". Das ist extrem hoch für kleine Server!

Die Faustformel für PostgreSQL shared_buffers lautet:

\text{Buffer}_{opt} = \text{Gesamt-RAM} \times 0{,}25

Hast du also nur 4 GB RAM, setze den Wert auf „1024MB“. Bei 2 GB RAM auf „512MB“.

Erstelle die Datei: nano containers/app.yml

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

params:
  db_default_text_search_config: "pg_catalog.english"
  # ⚠️ ACHTUNG: Passe diesen Wert an deinen RAM an (siehe Formel oben)!
  db_shared_buffers: "4096MB"
  db_work_mem: "40MB"

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  # Domain & Mail Konfiguration
  DISCOURSE_HOSTNAME: "example.com"
  DISCOURSE_DEVELOPER_EMAILS: "admin@example.com"
  DISCOURSE_SMTP_ADDRESS: "smtp.example.com"
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: "admin@example.com"
  DISCOURSE_SMTP_PASSWORD: "TestPass123!"
  DISCOURSE_SMTP_ENABLE_START_TLS: true
  DISCOURSE_SMTP_DOMAIN: "example.com"
  DISCOURSE_SMTP_AUTHENTICATION: "login"

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](https://github.com/discourse/docker_manager.git)

run:
  - exec: echo "Beginning of custom commands"
  # Fix für Redis & Backup Rechte
  - exec: chown -R redis:redis /var/lib/redis
  - exec: chmod 775 /var/lib/redis
  - exec: chown -R www-data:www-data /shared/backups && chmod -R 755 /shared/backups
  # Fix für Postgres Rechte (kritisch bei Upgrades!)
  - exec: chown -R postgres:postgres /shared/postgres_data && chmod -R 755 /shared/postgres_data
  - exec: chown -R postgres:postgres /var/run/postgresql && chmod -R 777 /var/run/postgresql
  - exec: echo "End of custom commands"

docker_args:
  - "--network=proxy"

labels:
  traefik.enable: "true"
  traefik.http.routers.discourse.rule: "Host(`example.com`)"
  traefik.http.routers.discourse.entrypoints: "websecure"
  traefik.http.routers.discourse.tls: "true"
  traefik.http.routers.discourse.tls.certresolver: "http_resolver"
  # ⚠️ Diese Middlewares müssen in Traefik existieren, sonst startet der Container nicht!
  traefik.http.routers.discourse.middlewares: "default@file,traefik-crowdsec-bouncer@file,middlewares-authelia@file,my-fail2ban@docker,my-get-real-ip@docker,gzip@file"
  traefik.http.services.discourse.loadbalancer.server.port: "80"
  traefik.docker.network: "proxy"

:rocket: Schritt 3: Bootstrap & Start

Jetzt wird das Image gebaut, Assets kompiliert (das dauert!) und die Datenbank initialisiert.

./launcher bootstrap app

:stopwatch: Dauer: ca. 5–10 Minuten. Hol dir einen Kaffee. :hot_beverage:

Wenn keine Fehler auftreten (suche nach rake db:migrate am Ende der Logs), starte den Container:

./launcher start app

:bust_in_silhouette: Schritt 4: Admin erstellen (Notfall-Methode)

Sollte deine SMTP-Konfiguration noch haken und du bekommst keine Bestätigungsmail, kannst du den Admin manuell erstellen:

./launcher enter app
rake admin:create
# Folge den Anweisungen (Email, Passwort)
exit

:wrench: Troubleshooting Guide

Läuft nicht? Hier sind die häufigsten Lösungen für dieses Setup:

Problem Mögliche Ursache Lösung
502 Bad Gateway Container fährt noch hoch oder Netzwerk falsch. Prüfe docker logs traefik und warte 2 Min nach Start.
Postgres Permission Denied Rechte auf dem Host-Volume falsch. ./launcher enter app, dann chown -R postgres:postgres /shared/postgres_data.
Seite lädt nicht (404) Traefik Labels matchen nicht. Prüfe, ob alle Middlewares (z.B. middlewares-authelia) in Traefik definiert sind.
Datenbank Fehler nach Upgrade Inkompatible Postgres Version. Nutze das tianon/postgres-upgrade Image für die Migration.

Diagnose-Befehle

  • Läuft der Container im richtigen Netz?
    docker ps (Prüfe Spalte „PORTS“ – sollte leer sein, aber Status „Up“).
  • Was sagt CrowdSec?
    Schau in /var/log/traefik oder nutze cscli metrics, um zu sehen, ob IPs geblockt werden.

Viel Erfolg mit deinem neuen Forum!
Fragen zum Traefik-Routing oder zur Postgres-Optimierung? Schreib es in die Kommentare! :backhand_index_pointing_down: