Discourse hinter Apache – und die E-Mail-Odyssee, die keiner wollte
Ich wollte nur schnell ein Forum aufsetzen. Am Ende hab ich DNS-Records getraced, DMARC-Reports gelesen – und bin trotzdem restlos begeistert.
- Schlagworte
- #Self-Hosting #Docker #Discourse #E-Mail #DNS #Homelab
- veröffentlicht
- Lesezeit
- 6 Minuten
Ich geb’s zu: Ich hab mir das langweilig vorgestellt. Docker-Container hochziehen, Domain dran, fertig. Discourse installieren, dachte ich, ist eine Sache von einer Stunde.
Es wurde ein ganzer Samstagnachmittag. Der Container war das kleinste Problem. Die eigentliche Geschichte ist eine über DNS-Records, drei verschiedene E-Mail-Anbieter und die Erkenntnis, dass meine Domain gar nicht dort liegt, wo ich dachte.
Am Ende lief alles. Und ich bin seitdem ziemlich verliebt in dieses Forum.
Für naehecke.fun – ein Näh-Community-Projekt – sollte ein Forum entstehen. Hier ist, was dabei rauskam.
Der Container: Unspektakulär und genau richtig
Discourse kommt offiziell als discourse_docker-Repo von GitHub, gesteuert über eine einzige YAML-Config pro Instanz. Bei mir liegt das Ganze bewusst nicht im vorgesehenen /var/discourse, sondern in meinem eigenen Docker-Verzeichnis – einfach weil ich alle meine Docker-Projekte an einem Ort halte. Ging problemlos, man passt dafür nur die volumes in der Config an.
Der Container läuft intern auf 127.0.0.1:8081, ganz ohne eigenes SSL – die SSL-Templates in der YAML sind bei mir auskommentiert. Warum? Weil mein Apache auf dem Server sowieso schon die komplette SSL-Terminierung für alle anderen Dienste macht. Da war es unsinnig, Discourse nochmal ein eigenes Zertifikatsmanagement aufbauen zu lassen.
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
ProxyPass / http://127.0.0.1:8081/
ProxyPassReverse / http://127.0.0.1:8081/
Speicher war auch kein Thema – bei 14 GB RAM und ordentlich Swap läuft das mit UNICORN_WORKERS: 4 sehr entspannt. Zum Steuern hab ich mir ein kleines discourse.sh gebastelt mit start, stop, restart, status, logs, update (git pull + rebuild + cleanup) und shell. Nichts Besonderes, aber es spart jedes Mal das Nachdenken über die richtigen launcher-Befehle.
Kleines Problem: Jeder Besucher hieß 172.17.0.1
Erste echte Überraschung: In den Discourse-Logs sah jeder Besucher gleich aus – nämlich wie die Docker-Gateway-IP. Macht Sinn, wenn man drüber nachdenkt: Der Container sieht nur den Apache-Proxy, nicht den eigentlichen Client.
Die Lösung liegt in der nginx-Config innerhalb des Containers, die man über einen run:-Block in der YAML patchen kann:
run:
- exec: echo "Beginning of custom commands"
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: /server.+{/
to: |
server {
set_real_ip_from 172.16.0.0/12;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
- exec: echo "End of custom commands"
Wichtig: set_real_ip_from nur auf das eigene Docker-Netz beschränken, sonst könnte jeder Client seine IP über den Header selbst fälschen. Nach einem Rebuild zeigten die Logs dann endlich echte Besucher-IPs statt der immer gleichen Gateway-Adresse.
E-Mail: Der Teil, der eigentlich den ganzen Nachmittag gefressen hat
Hier wird’s spannend. Und ehrlich gesagt auch ein bisschen zum Kopfschütteln über mich selbst.
Mein erster Ansatz: SMTP über meinen Strato-Account, Login cloud@palms-net.de, Absender noreply@forum.naehecke.fun. Klang plausibel. War es nicht.
550 5.7.1 ... is not an authorized sender
Jede Aktivierungsmail scheiterte. Der Grund, den ich erst nach einigem Grübeln verstand: Strato lässt nur Absenderadressen zu, die zum eigenen, dort authentifizierten Domain-Paket gehören. Und naehecke.fun liegt gar nicht bei Strato.
Die Diagnosekette
Weil ich mich wegen des Mailproblems nicht mal regulär als Admin einloggen konnte, musste ich erstmal ranstricken:
- In die Rails-Konsole des Containers (
./launcher enter→rails c) und den Mailversand direkt testen. - Meinen Admin-Account händisch aktivieren – ohne Mailbestätigung, per
User.find_by_email(...).activateund.grant_admin!. - Dann DNS-Forensik:
dig +trace TXT naehecke.funzeigte den SPF-Record:v=spf1 include:_smtp.udag.de ~all.udagsteht für United Domains – nicht Strato. Die MX-Records zeigten die zuständige Infrastruktur für eingehende Mail. SPF und MX beschrieben damit die DNS-Konfiguration der Domain, belegten aber für sich genommen noch nicht, über welchen Dienst meine konkrete Testmail tatsächlich rausging – der fehlgeschlagene Versand lief ja weiterhin über den zuvor konfigurierten Strato-Account. - Ein echter Mail-Header (Testmail an GMX) machte den Rest sichtbar: DKIM
pass, aber für die falsche Domain (palms-net.destattforum.naehecke.fun). SPF nurpassfür eine SRS-umgeschriebene Adresse. Und DMARC: fail, weil nichts zurFrom:-Domain aligned war.
Die Mail kam trotzdem an.
p=nonebedeutet nämlich, dass DMARC nichts an der bestehenden Zustellung ändern soll – es ist ein reiner Monitoring-Modus, keine Ablehnungs-Policy. Bei einem strengeren Empfänger mit eigener, restriktiverer Policy hätte es aber knapp werden können.
Das war der Moment, in dem klar wurde: Man kann sich nicht einfach irgendeinen SMTP-Account leihen und hoffen, dass es passt. E-Mail-Zustellung ist im Kern eine Vertrauensfrage zwischen Domains – und die muss technisch stimmen, nicht nur gefühlt.
Die Lösung
Postfach forum@naehecke.fun bei United Domains angelegt – dort, wo die Domain tatsächlich liegt – und die SMTP-Zugangsdaten in die Discourse-Config eingetragen. notification email im Admin-Bereich entsprechend umgestellt.
Ergebnis beim erneuten Test: DKIM pass, SPF pass, DMARC pass. Saubere Alignment, alles authentifiziert. So, wie es von Anfang an hätte sein sollen.
Die Lektion, die bleibt: Bevor man irgendeinen SMTP-Zugang für eine neue Domain benutzt, erstmal nachsehen, wo die Domain wirklich liegt. dig ist dabei die Wahrheit, nicht die eigene Erinnerung an alte Verträge.
Kleinigkeiten, die auch noch dranhingen
- Updates: Für reguläre Discourse-Updates reicht
/admin/upgradeim laufenden Container. Ein./launcher rebuildbraucht man nur bei Änderungen am Basis-Image, an Plugins oder an der YAML selbst. - Rechte: Standardmäßig dürfen nur Admins Kategorien anlegen. Moderatoren erst, wenn man die Einstellung
moderators manage categories and groupsexplizit aktiviert. - Footer-Links zur Hauptseite: Bei den mitgelieferten Themes ist der Code gesperrt – kein direktes Editieren. Die saubere Lösung ist ein eigenes Theme-Component. Alternativ reichen für den Anfang auch einfach Links im Sidebar-Bereich „Community“.
- Mail-Empfang: Bewusst nicht eingerichtet – kein POP3-Abruf,
reply by emailaus. Das Postfach bleibt trotzdem sinnvoll, um Bounces zu sehen. Empfehlung an mich selbst: eine Weiterleitung einrichten statt alles kommentarlos zu verwerfen. must approve users: Neue Anmeldungen landen erstmal in der Review-Queue (/review), Moderatoren bekommen nach einer einstellbaren Frist (pending users reminder delay minutes) eine Erinnerung. Für eine kleine Community genau die richtige Balance zwischen Offenheit und Kontrolle.- Logo: Aus einem simplen Foto (ein Nähfuß mit Ziernähten) ließ sich ein komplettes Set bauen – Header-Logo hell/dunkel, kleines Logo, Favicon, Apple-Touch-Icon, OpenGraph-Bild. Discourse will das alles einzeln, aber es lohnt sich für den ersten Eindruck.
Fazit: Trotz allem – ich bin hin und weg
Der Aufwand war größer als erwartet. Aber nicht wegen Discourse selbst, sondern wegen meiner eigenen falschen Annahme über meine Domain-Infrastruktur. Einmal die E-Mail-Kette sauber aufgelöst, läuft die Sache seitdem völlig unauffällig durch.
Und Discourse selbst? Ist richtig gut. Das Admin-Interface ist durchdacht, die Review-Queue macht Moderation angenehm statt nervig, und für eine kleine, feine Community wie naehecke.fun ist es genau die richtige Größe – nicht der Overkill, den man bei manch anderer Forensoftware befürchten muss.
Wer selbst hosten will: Rechnet die E-Mail-Konfiguration realistisch mit ein. Das ist der Teil, der über “läuft” oder “läuft nicht” entscheidet – nicht der Container selbst.
Bleibt neugierig, Alex