Mailpit per Docker Compose einrichten: E-Mails aus Anwendungen sicher abfangen
Mailpit nimmt alle E-Mails einer Anwendung entgegen, ohne sie zuzustellen, und zeigt sie in einer Weboberfläche an. Diese Anleitung führt durch Installation, Absicherung, Betrieb, Backup und Wiederherstellung mit Docker Compose.

Wer eine Webanwendung, ein ERP-System oder eine Testinstanz eines Shops betreibt, kennt das Risiko: Ein Testlauf verschickt versehentlich echte E-Mails an echte Kundenadressen. Aus einem harmlosen Importtest werden dann tausend Bestellbestätigungen an Menschen, die gar nichts bestellt haben. Mailpit löst dieses Problem, indem es sich als SMTP-Server ausgibt, alle eingehenden Nachrichten annimmt und keine einzige weiterleitet.
Das Werkzeug ersetzt damit das seit Jahren nicht mehr gepflegte MailHog. Es läuft als einzelne ausführbare Datei ohne Abhängigkeiten, braucht im Betrieb nur wenige Megabyte Arbeitsspeicher und bringt neben der Weboberfläche eine Programmierschnittstelle für automatisierte Tests mit. Diese Anleitung zeigt die vollständige Einrichtung per Docker Compose.
Was Mailpit leistet und wo die Grenzen liegen
Mailpit nimmt E-Mails per SMTP entgegen, speichert sie in einer eingebetteten Datenbank und zeigt sie in einer Weboberfläche an. Dort lassen sich die formatierte HTML-Ansicht, der HTML-Quelltext, die Textfassung, die Kopfzeilen, die Rohfassung und Anhänge betrachten. Zusätzlich gibt es eine Suche, eine Prüfung der HTML-Verträglichkeit mit gängigen Mailprogrammen, eine Prüfung enthaltener Verweise und auf Wunsch einen POP3-Server, mit dem sich die gesammelten Nachrichten in ein normales Mailprogramm holen lassen.
Das Projekt wird unter github.com/axllent/mailpit entwickelt und steht unter der MIT-Lizenz. Zum Abrufzeitpunkt am 13. September 2026 weist das Repository 10.351 Sterne auf, der letzte Push stammt vom 6. September 2026, die aktuelle Veröffentlichung ist v1.31.1 vom 5. September 2026. Das Projekt ist damit aktiv gepflegt.
Wichtig sind die Grenzen. Mailpit ist kein Mailserver für den Produktivbetrieb. Es stellt keine E-Mails an externe Empfänger zu, es hat keine Postfachverwaltung und es ist nicht für den dauerhaften Empfang echter Geschäftspost gedacht. Wer einen echten Mailserver braucht, ist mit Postfix und Dovecot oder einer fertigen Zusammenstellung besser bedient. Mailpit ist ein Auffangbecken für Testumgebungen, Entwicklungsinstanzen und automatisierte Tests.
Eine Besonderheit ist die Weiterleitungsfunktion: Mailpit kann einzelne Nachrichten auf Knopfdruck über einen echten SMTP-Server versenden oder automatisch an feste Adressen weiterleiten. Damit lässt sich gezielt eine einzelne Testmail an einen Kollegen schicken, ohne die Sperre für alle Nachrichten aufzuheben.
Voraussetzungen und Ressourcen
- Ein Linux-Host mit Docker Engine und dem Compose-Plugin. Die Beispiele in dieser Anleitung wurden mit Docker 29.1.3 und Docker Compose 2.40.3 auf Ubuntu geprüft.
- Etwa 100 MB Arbeitsspeicher im Leerlauf. Der geprüfte Container meldete über die Programmierschnittstelle einen Speicherverbrauch von rund 9 MB für den eigentlichen Prozess.
- Speicherplatz nach Bedarf. Die Datenbank wächst mit der Anzahl gespeicherter Nachrichten, standardmäßig sind maximal 500 Nachrichten vorgesehen, im Beispiel unten werden 5000 gesetzt.
- Zwei freie Ports auf dem Host: 8025 für die Weboberfläche und 1025 für SMTP. Beide lassen sich verschieben.
- Unterstützte Architekturen: Es gibt Abbilder für mehrere Plattformen, unter anderem amd64 und arm64. Der Betrieb auf einem Kleinrechner mit ARM-Prozessor oder einem NAS ist damit möglich.
Installation mit Docker Compose
Zuerst ein Verzeichnis für den Stack anlegen. Der Ort ist frei wählbar, im Beispiel liegt er unter /opt.
sudo mkdir -p /opt/mailpit
cd /opt/mailpit
Dann die Datei compose.yaml mit folgendem Inhalt anlegen. Sie entspricht dem offiziellen Beispiel aus der Mailpit-Dokumentation, ergänzt um eine feste Version und ein benanntes Volume statt eines Verzeichnisses im Arbeitsverzeichnis.
services:
mailpit:
image: axllent/mailpit:v1.31.1
container_name: mailpit
restart: unless-stopped
ports:
- "8025:8025"
- "1025:1025"
volumes:
- mailpit_data:/data
environment:
MP_DATABASE: /data/mailpit.db
MP_MAX_MESSAGES: "5000"
MP_SMTP_AUTH_ACCEPT_ANY: "1"
MP_SMTP_AUTH_ALLOW_INSECURE: "1"
TZ: Europe/Berlin
volumes:
mailpit_data:
Die einzelnen Werte im Überblick:
imagemit fester Version stattlatest. Damit ist nachvollziehbar, welche Version läuft, und ein Neustart zieht nicht unbemerkt eine neue Hauptversion.MP_DATABASElegt die Datenbankdatei in das eingebundene Volume. Ohne diesen Wert hält Mailpit die Nachrichten nur im Arbeitsspeicher und verliert sie beim Neustart.MP_MAX_MESSAGESbegrenzt die Anzahl gespeicherter Nachrichten. Ältere werden automatisch entfernt, sobald die Grenze erreicht ist. Der Standardwert der Anwendung liegt bei 500.MP_SMTP_AUTH_ACCEPT_ANYnimmt beliebige Anmeldedaten am SMTP-Port an, auch gar keine. Das ist für Testumgebungen praktisch, weil die Anwendung ihre bestehende Konfiguration behalten kann.MP_SMTP_AUTH_ALLOW_INSECUREerlaubt unverschlüsselte Anmeldeverfahren. In Verbindung mit dem vorigen Wert bedeutet das: Der SMTP-Port darf unter keinen Umständen aus dem Internet erreichbar sein.TZsorgt dafür, dass die Zeitstempel in der Oberfläche der lokalen Zeit entsprechen.
Anschließend den Stack starten:
sudo docker compose up -d
Funktionsprüfung
Die folgenden Prüfungen wurden für diese Anleitung tatsächlich ausgeführt, die gezeigten Ausgaben stammen aus dem realen Lauf.
Zuerst der Zustand des Containers:
sudo docker compose ps
Die Ausgabe zeigte den Container als gesund:
NAME IMAGE SERVICE STATUS PORTS
mailpit-test axllent/mailpit:v1.31.1 mailpit Up 29 seconds (healthy) 0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp, 1110/tcp
Der Port 1110 im letzten Feld ist der POP3-Dienst, der im Abbild vorbereitet ist, aber erst mit einer Passwortdatei aktiv wird.
Dann die Programmierschnittstelle abfragen:
curl -s http://127.0.0.1:8025/api/v1/info
Antwort aus dem Testlauf, gekürzt:
{"Version":"v1.31.1","LatestVersion":"v1.31.1","Database":"/data/mailpit.db","DatabaseSize":94208,"Messages":0,"Unread":0}
Jetzt eine Testmail einliefern. Das folgende Python-Skript erzeugt eine Nachricht mit Text- und HTML-Teil und schickt sie an den SMTP-Port:
python3 - <<'EOF'
import smtplib
from email.message import EmailMessage
m = EmailMessage()
m["From"] = "app@example.test"
m["To"] = "admin@example.test"
m["Subject"] = "Testmail aus der Anwendung"
m.set_content("Klartext-Variante")
m.add_alternative("<h1>Rechnung</h1><p>HTML-Variante</p>", subtype="html")
s = smtplib.SMTP("127.0.0.1", 1025)
s.send_message(m)
s.quit()
print("gesendet")
EOF
Danach die gespeicherten Nachrichten abrufen:
curl -s http://127.0.0.1:8025/api/v1/messages
Im Testlauf lieferte die Schnittstelle eine Nachricht mit dem Betreff der Testmail, dem Absender app@example.test und dem Empfänger admin@example.test zurück. Die Zählung unter SMTPAccepted in der Info-Abfrage stieg von 0 auf 1. Damit sind Annahme, Speicherung und Abruf belegt.
Die Weboberfläche ist anschließend unter http://serveradresse:8025 erreichbar und zeigt dieselbe Nachricht mit HTML-Vorschau und Quelltextansicht.
Absicherung und Netzwerkfreigabe
Dieser Punkt ist der wichtigste der ganzen Anleitung. Mailpit ist in der Standardkonfiguration vollständig offen: Die Weboberfläche hat keine Anmeldung, und der SMTP-Port nimmt Nachrichten ohne Authentifizierung entgegen. Eine so betriebene Instanz im Internet ist ein offenes Weiterleitungsrelais aus Sicht eines Angreifers und ein Datenleck, weil jede abgefangene Nachricht öffentlich einsehbar ist.
Es gibt zwei Wege, das abzusichern. Der einfachere und für die meisten Fälle ausreichende Weg ist die Bindung an die lokale Adresse. Dazu in der compose.yaml die Portangaben ändern:
ports:
- "127.0.0.1:8025:8025"
- "127.0.0.1:1025:1025"
Damit ist Mailpit nur noch vom Server selbst erreichbar. Der Zugriff auf die Oberfläche erfolgt dann über einen SSH-Tunnel:
ssh -L 8025:127.0.0.1:8025 benutzer@serveradresse
Läuft die sendende Anwendung selbst in Docker, sollte sie im selben Compose-Netzwerk liegen. Dann genügt der Dienstname als SMTP-Host, und der Port muss gar nicht auf den Host veröffentlicht werden:
# ports-Eintrag fuer 1025 entfaellt, stattdessen gemeinsames Netzwerk
networks:
- intern
networks:
intern:
Der zweite Weg ist ein Reverse Proxy mit Verschlüsselung und Anmeldung. Mailpit bringt dafür eine eigene Anmeldung mit, die über eine Passwortdatei aktiviert wird. Zuerst die Datei im Volume anlegen:
sudo docker exec -it mailpit sh -c 'printf "admin:%s\n" "$(openssl passwd -apr1 IhrPasswort)" > /data/authfile'
Dann in der compose.yaml ergänzen und den Stack neu starten:
MP_UI_AUTH_FILE: /data/authfile
Die dazugehörige Konfiguration für einen Reverse Proxy mit Caddy sieht so aus:
mail-test.example.de {
reverse_proxy 127.0.0.1:8025
}
Caddy holt das Zertifikat automatisch. Wichtig bleibt: Der SMTP-Port gehört auch bei dieser Variante nicht ins Internet. Er wird nur intern von der sendenden Anwendung genutzt.
Ergänzend die Firewall prüfen. Mit der einfachen Firewall unter Ubuntu:
sudo ufw status
sudo ufw deny 1025/tcp
Ein Hinweis zu Docker: Veröffentlichte Container-Ports umgehen in vielen Konfigurationen die Regeln der Host-Firewall, weil Docker eigene Regeln in der Paketfilterkette anlegt. Die Bindung an 127.0.0.1 in der Portangabe ist deshalb die zuverlässigere Absicherung als eine nachträgliche Firewallregel.
Persistente Daten und Rechte
Alle Daten liegen im Volume unter /data. Der Inhalt nach dem Testlauf:
sudo docker run --rm -v mailpit_mailpit_data:/data alpine ls -la /data
Ausgabe aus dem realen Lauf:
-rw-r--r-- 1 root root 4096 mailpit.db
-rw-r--r-- 1 root root 32768 mailpit.db-shm
-rw-r--r-- 1 root root 490312 mailpit.db-wal
Die beiden Dateien mit den Endungen -shm und -wal gehören zur Schreibprotokollierung der eingebetteten Datenbank. Sie müssen beim Sichern mitgenommen werden, sonst fehlen die zuletzt geschriebenen Nachrichten.
Ein benanntes Volume ist gegenüber einem eingebundenen Hostverzeichnis vorzuziehen, weil Docker die Rechte selbst verwaltet. Wer trotzdem ein Hostverzeichnis nutzen möchte, etwa weil ein bestehender Sicherungsauftrag darauf zugreift, muss die Rechte selbst setzen:
sudo mkdir -p /opt/mailpit/data
sudo chown -R 1000:1000 /opt/mailpit/data
Wird das Netzwerkdateisystem NFS als Ablage genutzt, ist zusätzlich die Option --disable-wal beziehungsweise die entsprechende Umgebungsvariable nötig, weil die Schreibprotokollierung der Datenbank auf NFS Probleme macht.
Backup und Wiederherstellung
Für eine Testumgebung ist die Sicherung meist nicht kritisch, aber der Ablauf gehört trotzdem geprüft. Die folgenden Schritte wurden für diese Anleitung durchgeführt und haben funktioniert.
Sicherung des gesamten Volumes in ein Archiv:
sudo docker run --rm \
-v mailpit_mailpit_data:/data \
-v /var/backups:/backup \
alpine tar czf /backup/mailpit-$(date +%F).tgz -C /data .
Im Testlauf entstand daraus ein Archiv von rund 8 KB für eine gespeicherte Nachricht.
Die Wiederherstellung in ein neues Volume:
sudo docker volume create mailpit_restore
sudo docker run --rm \
-v mailpit_restore:/data \
-v /var/backups:/backup \
alpine tar xzf /backup/mailpit-2026-09-13.tgz -C /data
Anschließend eine Instanz auf dem wiederhergestellten Volume starten und prüfen:
sudo docker run -d --name mailpit-restore \
-p 8125:8025 \
-v mailpit_restore:/data \
-e MP_DATABASE=/data/mailpit.db \
axllent/mailpit:v1.31.1
curl -s http://127.0.0.1:8125/api/v1/messages
Die Abfrage lieferte im Testlauf die zuvor gesicherte Nachricht mit dem Betreff der Testmail zurück. Damit ist die Wiederherstellung nicht nur behauptet, sondern belegt.
Für eine saubere Sicherung im laufenden Betrieb bietet Mailpit zusätzlich den Unterbefehl dump, der alle Nachrichten als einzelne Dateien in ein Verzeichnis schreibt. Das ist der bessere Weg, wenn die Nachrichten längerfristig aufbewahrt werden sollen, weil das Ergebnis unabhängig vom Datenbankformat lesbar bleibt.
Updates und Rollback
Das Update erfolgt über die Versionsangabe in der compose.yaml. Der Ablauf:
cd /opt/mailpit
sudo docker compose down
sudo cp compose.yaml compose.yaml.bak
# image-Zeile auf die neue Version aendern
sudo docker compose pull
sudo docker compose up -d
sudo docker compose logs -f --tail 50
Ein Rollback auf die vorherige Version ist möglich, solange das alte Abbild noch lokal vorliegt oder erneut geladen werden kann. Die Grenze liegt beim Datenbankschema: Wenn eine neue Hauptversion das Schema anpasst, kann die ältere Version die bereits migrierte Datenbank unter Umständen nicht mehr lesen. Vor einem Versionssprung über eine Hauptversion hinweg deshalb immer zuerst die Sicherung anlegen und im Zweifel die Versionshinweise des Projekts lesen.
Weil Mailpit ein Testwerkzeug ist, ist der Datenverlust im Fehlerfall meist verschmerzbar. Das ist ein Vorteil gegenüber produktiven Diensten, sollte aber kein Argument gegen die Sicherung sein.
Typische Fehler und Lösungen
Die Anwendung meldet Verbindung verweigert auf Port 1025. Häufigste Ursache bei Anwendungen im Container: Als SMTP-Host ist localhost eingetragen. Innerhalb eines Containers zeigt localhost auf den Container selbst, nicht auf den Host. Stattdessen den Dienstnamen aus der Compose-Datei eintragen, also mailpit, und beide Container ins selbe Netzwerk legen.
Nachrichten verschwinden nach einem Neustart. Dann fehlt entweder das Volume oder die Variable MP_DATABASE. Ohne Angabe einer Datenbankdatei hält Mailpit alles nur im Arbeitsspeicher.
Alte Nachrichten verschwinden im laufenden Betrieb. Das ist kein Fehler, sondern die Begrenzung über MP_MAX_MESSAGES beziehungsweise der Standardwert von 500. Wer mehr aufbewahren will, setzt den Wert hoch oder nutzt zusätzlich die Begrenzung nach Alter.
Port 8025 ist bereits belegt. Ein anderer Dienst nutzt den Port. Die Hostseite der Portangabe ändern, etwa auf 8035:8025. Die Containerseite bleibt unverändert.
Die Weboberfläche zeigt beim Betrieb hinter einem Reverse Proxy in einem Unterpfad nichts an. Dann fehlt die Angabe des Webwurzelverzeichnisses. Mit der Option webroot beziehungsweise der entsprechenden Umgebungsvariable den Pfad setzen, unter dem die Oberfläche erreichbar ist.
Die Datenbank verhält sich auf einem Netzlaufwerk merkwürdig. Die Schreibprotokollierung der eingebetteten Datenbank verträgt sich nicht mit NFS. Mit der Option zum Abschalten der Schreibprotokollierung starten oder die Datenbank auf lokalem Speicher ablegen.
Der Container startet, aber die Anmeldung greift nicht. Die Passwortdatei muss im eingebundenen Volume liegen und im Format Benutzername Doppelpunkt Passworthash vorliegen. Ein einfaches Klartextpasswort in der Datei funktioniert nicht.
Saubere Deinstallation
Zum Entfernen zuerst die Container stoppen und löschen. Dieser Schritt lässt die Daten unangetastet:
cd /opt/mailpit
sudo docker compose down
Sollen auch die gespeicherten Nachrichten verschwinden, kommt zusätzlich das Volume weg. Achtung: Der folgende Befehl löscht alle gespeicherten Nachrichten und die Passwortdatei unwiderruflich. Legen Sie vorher eine Sicherung an, wenn die Daten noch gebraucht werden.
sudo docker compose down -v
Danach noch das Abbild entfernen, falls es nicht mehr gebraucht wird:
sudo docker image rm axllent/mailpit:v1.31.1
sudo rm -rf /opt/mailpit
Nicht vergessen: Die SMTP-Einstellungen der sendenden Anwendungen zeigen danach ins Leere. Sie müssen vor dem Abbau wieder auf den vorherigen Wert gesetzt werden, sonst laufen Testläufe in Fehlermeldungen.
Was tatsächlich geprüft wurde
Für diese Anleitung wurden folgende Schritte in einer isolierten Testumgebung mit Docker 29.1.3 und Compose 2.40.3 tatsächlich ausgeführt: Start des Stacks, Zustandsprüfung des Containers, Abfrage der Info-Schnittstelle, Einlieferung einer Testmail per SMTP, Abruf der gespeicherten Nachricht über die Programmierschnittstelle, Sicherung des Volumes in ein Archiv, Wiederherstellung in ein neues Volume und Start einer zweiten Instanz auf den wiederhergestellten Daten mit erfolgreicher Anzeige der Nachricht.
Nicht selbst ausgeführt, sondern der offiziellen Dokumentation entnommen wurden: der Betrieb hinter einem Reverse Proxy mit Zertifikat, die Anmeldung über die Passwortdatei, der POP3-Betrieb und das Verhalten auf NFS-Ablagen. Diese Angaben stammen aus der Projektdokumentation und den eingebauten Hilfetexten der Anwendung, die im Testlauf eingesehen wurden.
Passende Anleitungen auf S-EDV
- Docker Compose unter Linux als Grundlage für Selfhosting erklärt die Bausteine, die hier verwendet werden.
- Caddy als Reverse Proxy mit automatischem HTTPS ergänzt die Absicherung der Weboberfläche.
- Eigener Mailserver mit Docker Mailserver ist die passende Lösung, wenn statt eines Auffangservers ein echter Mailbetrieb gebraucht wird.
Quellen
- Projekt-Repository axllent/mailpit auf GitHub, Kennzahlen abgerufen am 13. September 2026
- Mailpit-Dokumentation: Docker images
- Mailpit: Veröffentlichungen, Version v1.31.1 vom 5. September 2026