Ich wache also morgens auf, trinke gemĂŒtlich meinen Kaffee, öffne mein Mail-Interface â und⊠Stille. Kein Mailversand, kein Empfang.
Das Login-Interface meiner Mailcow-Instanz (auf einem Hetzner ARM64-Server) lud zwar noch, aber die Mails steckten fest. Der Server konnte nicht einmal mehr eine IP curlen.
Ich ahnte schon: Das war wohl das Debian-Update von letzter Nacht. đ
đ Der erste VerdĂ€chtige: Unbound
Ein Blick ins docker compose ps offenbarte:
mailcowdockerized-unbound-mailcow-1 ... unhealthy
Und das Log zeigte den ĂbeltĂ€ter:
curl: (28) Failed to connect to www.internic.net port 443 ...
Unbound wollte beim Start die Root-Hints von internic.net ziehen â doch ohne funktionierendes DNS (ja, Henne-Ei-Problem) blieb er stecken.
Das Resultat:
Mailcow startete zwar, aber alle Container, die auf DNS angewiesen sind â von Postfix bis Rspamd â liefen ins Leere.
âïž Schritt 1 â Docker wieder Internet geben
Das Debian-Update hatte offenbar das Netzwerk-Setup oder systemd-resolved durcheinandergebracht.
Lösung: Docker bekommt feste Resolver.
cat >/etc/docker/daemon.json <<'JSON'
{
"dns": ["1.1.1.1", "9.9.9.9"]
}
JSON
systemctl restart docker
Damit hat jeder Container beim Start Zugriff auf Cloudflare und Quad9.
âĄïž Schritt 2 â Root-Hints manuell nachladen
Da Unbound sich die Root-Zone-Datei nicht mehr ziehen konnte, hab ich sie selbst bereitgestellt:
curl -fsSL https://www.internic.net/domain/named.root -o /tmp/root.hints
docker cp /tmp/root.hints mailcowdockerized-unbound-mailcow-1:/etc/unbound/root.hints
docker exec -it mailcowdockerized-unbound-mailcow-1 sh -c \
'unbound-anchor -a /var/lib/unbound/root.key -v; chown unbound:unbound /var/lib/unbound/root.key'
docker compose restart unbound-mailcow
Nach einem Neustart war der Container endlich wieder healthy. đ
đŹ Schritt 3 â âTemporary lookup failureâ beim Mailversand
Doch kaum dachte ich, das System sei wieder heil, kam der nÀchste Schlag:
451 4.3.0 Temporary lookup failure
warning: texthash:/opt/mailcow-dockerized/data/conf/postfix/transport-extra.cf ...
Postfix beschwerte sich ĂŒber eine fehlende Transport-Map.
Diese transport-extra.cf wird standardmĂ€Ăig referenziert, existierte aber schlicht nicht mehr.
đ§ Schritt 4 â Postfix in Docker richtig konfigurieren
Das Problem: In den Konfig-Dateien stand ein Host-Pfad (/opt/mailcow-dockerized/...), den der Container gar nicht kennt.
Im Container-Kontext muss die Variable ${config_directory} verwendet werden â sie zeigt auf /etc/postfix.
Ein beherztes Suchen & Ersetzen brachte die Rettung:
grep -Rin "transport-extra\.cf|transport_maps" /opt/mailcow-dockerized/data/conf/postfix
sed -i 's#/opt/mailcow-dockerized/data/conf/postfix/transport-extra\.cf#${config_directory}/transport-extra.cf#g' \
/opt/mailcow-dockerized/data/conf/postfix/*.cf
Und natĂŒrlich eine leere Datei angelegt, falls sie nicht existiert:
touch /opt/mailcow-dockerized/data/conf/postfix/transport-extra.cf
chmod 644 /opt/mailcow-dockerized/data/conf/postfix/transport-extra.cf
docker compose restart postfix-mailcow
Ab da: keine Lookup-Fehler mehr. đ„ł
â Fazit â Fehlerursache & Lessons Learned
Der ganze Crash kam durch eine Kettenreaktion:
- Debian-Update â
systemd-resolved/ Docker-DNS gebrochen - Unbound konnte keine Root-Hints laden â âunhealthyâ
- Postfix bekam keine DNS-Antworten â Lookup-Fehler
- ZusÀtzlich: Falscher Pfad zu
transport-extra.cfâ 451-Fehler bei RCPT
Dauerhafte Lösung:
- Docker mit festen Resolvern (
1.1.1.1,9.9.9.9) - Unbound-Root-Hints und Trust-Anchor manuell initialisiert
- Postfix-Maps auf
${config_directory}umgestellt - Leere
transport-extra.cfbereitgestellt
Seitdem lĂ€uft der Mailcow-Stack wieder sauber â und ich trinke meinen Kaffee wieder entspannt. âïž
đ§ Bonus-Tipp:
Nach gröĂeren System-Updates lohnt sich ein schneller Testlauf:
docker inspect -f '{{.State.Health.Status}}' mailcowdockerized-unbound-mailcow-1
docker exec -it mailcowdockerized-postfix-mailcow-1 postconf -n | grep transport_maps
So merkt man sofort, ob Unbound oder Postfix zickt â bevor das erste âWarum bekomme ich keine Mails mehr?â eintrifft. đ

