Ein Docker-Container, der Resend als normales Mailkonto nutzbar macht. Man bekommt IMAP und SMTP und kann Outlook, Thunderbird oder ein Handy damit verbinden. Versendet und empfangen wird im Hintergrund über Resend.
Wer schon mal einen eigenen Mailserver betrieben hat, kennt das: Die Mails landen bei Gmail, Outlook & Co. direkt im Spam, weil die Server-IP keinen Ruf hat, auf irgendeiner Blacklist steht oder der Hoster Port 25 sperrt. Das in den Griff zu bekommen ist aufwendig.
Resend löst genau das. Die Mails gehen über deren Infrastruktur raus, mit sauberem SPF und DKIM, und kommen im Posteingang an. Resend ist aber eigentlich für Entwickler gedacht, also für Mails aus Anwendungen heraus wie Kontaktformulare oder Systemmails, und bietet nur eine API, kein Postfach.
Dieses Projekt ist extrem simpel gehalten und macht aus Resend ein ganz normales Mailkonto. Wenn die Domain bei Resend sowieso schon eingerichtet ist, bekommt man damit ein paar richtige Postfächer (info@, kontakt@, …) für Outlook oder das Handy, ohne zusätzlich einen Mailanbieter zu bezahlen und ohne selbst gegen den Spamordner zu kämpfen.
Dieser Container übernimmt nur den Teil dazwischen:
- Senden: Das Mailprogramm liefert per SMTP an den Container, der leitet die Mail unverändert an den SMTP-Relay von Resend weiter. DKIM, SPF und Zustellung übernimmt Resend.
- Empfangen: Der MX-Record der Domain zeigt auf Resend. Der Container fragt die Resend-API in einem festen Intervall nach neuen Mails, lädt jeweils die Originalmail herunter und legt sie ins passende Postfach.
- Postfächer: Dovecot stellt IMAP bereit, mit Ordnern, gelesen/ungelesen usw. Alles liegt lokal im Volume
./data.
Der Server braucht keinen eingehenden Port 25, und die IP-Reputation spielt keine Rolle.
- Resend-Account mit verifizierter Domain und aktiviertem Receiving (der MX-Record der Domain zeigt auf Resend)
- API-Key mit Full access. Mit „Sending access“ lassen sich empfangene Mails nicht abrufen.
- Server mit Docker und Docker Compose
- DNS-Eintrag
mail.<domain>→ IP des Servers. Bei Cloudflare ohne Proxy (graue Wolke), sonst kommen IMAP und SMTP nicht durch. - Freie TCP-Ports: 993 (IMAP), 465 und 587 (SMTP)
git clone <repo> resend2smtp && cd resend2smtp
cp .env.example .env.env:
MAIL_DOMAIN=example.com
RESEND_API_KEY=re_xxxxxxxx
MAIL_ACCOUNTS=kay, info
POLL_INTERVAL=30
| Variable | Bedeutung |
|---|---|
MAIL_DOMAIN |
Domain der Postfächer. Die Clients verbinden sich mit mail.<MAIL_DOMAIN>. |
RESEND_API_KEY |
API-Key von Resend (Full access) |
MAIL_ACCOUNTS |
Postfächer, die beim Start angelegt werden, falls sie noch nicht existieren |
POLL_INTERVAL |
Sekunden zwischen zwei Abrufen bei Resend (Standard 30) |
Ohne eigenes Zertifikat erzeugt der Container ein selbstsigniertes. Damit funktioniert es zwar, aber jedes Mailprogramm zeigt eine Warnung, und Outlook lässt sich damit nur umständlich einrichten. Besser ist ein Let's-Encrypt-Zertifikat. Liegt die Domain bei Cloudflare, geht das per DNS-Challenge ohne Webserver:
# API-Token in Cloudflare: Vorlage "Edit zone DNS", nur für die eigene Zone
echo "dns_cloudflare_api_token = <TOKEN>" > cloudflare.ini && chmod 600 cloudflare.ini
docker run --rm -v "$PWD/letsencrypt:/etc/letsencrypt" -v "$PWD/cloudflare.ini:/cloudflare.ini:ro" \
certbot/dns-cloudflare certonly --dns-cloudflare --dns-cloudflare-credentials /cloudflare.ini \
-d mail.example.com --agree-tos -m admin@example.com -n
mkdir -p certs
cp -L letsencrypt/live/mail.example.com/{fullchain,privkey}.pem certs/Der Container liest certs/fullchain.pem und certs/privkey.pem beim Start ein. Für die Erneuerung reicht ein monatlicher Cronjob:
0 4 1 * * cd /pfad/zu/resend2smtp && docker run --rm -v "$PWD/letsencrypt:/etc/letsencrypt" -v "$PWD/cloudflare.ini:/cloudflare.ini:ro" certbot/dns-cloudflare renew -q && cp -L letsencrypt/live/mail.example.com/*.pem certs/ && docker restart resend2smtp
docker compose up -d --build
docker compose logs | grep -A5 "NEW ACCOUNTS"Die Passwörter neu angelegter Postfächer stehen nur einmal im Log. Gespeichert werden nur Hashes.
Beim allerersten Start werden Mails übersprungen, die schon vorher bei Resend lagen. Danach wird jede neue Mail genau einmal zugestellt.
| Server | Port | Verschlüsselung | |
|---|---|---|---|
| IMAP | mail.example.com |
993 | SSL/TLS |
| SMTP | mail.example.com |
465 | SSL/TLS |
Alternativ SMTP über Port 587 mit STARTTLS. Benutzername ist die volle Adresse, das Passwort ist für IMAP und SMTP dasselbe. Beim Postausgangsserver muss „erfordert Authentifizierung“ aktiv sein, SPA dagegen aus.
Outlook: Der normale Einrichtungs-Assistent prüft den Server über die Microsoft-Cloud und bricht dabei gerne mit einem Timeout ab. Zuverlässig geht es über Systemsteuerung → Mail (Microsoft Outlook) → E-Mail-Konten → Neu → Manuelle Konfiguration → POP oder IMAP. Dort unter „Weitere Einstellungen → Erweitert“ die Ports wie oben eintragen, und zwar erst die Verschlüsselung wählen und danach den Port.
docker exec resend2smtp resend2smtp createacc info # neues Postfach, Passwort wird einmal angezeigt
docker exec resend2smtp resend2smtp resetpw kay # neues Zufallspasswort
docker exec resend2smtp resend2smtp resetpw kay MeinPasswort # Passwort selbst setzen
docker exec resend2smtp resend2smtp deleteacc info # Postfach löschen (Mails bleiben in ./data)Änderungen gelten sofort, ohne Neustart.
- Ein Postfach darf nur mit seiner eigenen Adresse senden (Envelope und
From:-Header werden geprüft). - Mails an Adressen ohne Postfach werden verworfen und geloggt.
- Pro Abruf werden die neuesten 100 empfangenen Mails bei Resend geprüft.
- Kein Spamfilter: Was Resend annimmt, landet im Posteingang.
- Maximale Mailgröße 40 MB (Limit von Resend).
- Der Relay zu Resend läuft über Port 2587, weil manche Hoster ausgehend 25/465/587 sperren.
./dataist der einzige Speicher der Mails und sollte regelmäßig gesichert werden. Resend ist kein Archiv.
app/resend2smtp/
__main__.py Start, Abruf-Schleife, Befehle
config.py Einstellungen aus der .env
accounts.py Postfächer (data/accounts, Dovecot passwd-file)
smtp_server.py SMTP 465/587 → Resend
inbound.py Resend-API abfragen → Zustellung per LMTP an Dovecot
dovecot_auth.py SMTP-Login gegen Dovecot prüfen
docker/
dovecot.conf IMAP und LMTP
entrypoint.sh startet Dovecot und den Python-Teil
Tests lokal:
python -m venv .venv && .venv/bin/pip install -r requirements.txt pytest
.venv/bin/python -m pytest tests