Zum Inhalt springen
Serverküche
Suche

Die Suche wird geladen … (nur in der veröffentlichten Seite verfügbar).

Anwendungen Schwierigkeit: Fortgeschritten

Stalwart: der schlanke Mailserver in einem Container

Stalwart Mail Server mit Docker aufsetzen: SMTP, IMAP, JMAP und Spam-Filter in einem einzigen, schlanken Container – die moderne Alternative zu Mailcow.

· 13 Min. Lesezeit ·Dauer: ca. 60 Minuten
Inhaltsverzeichnis

Ein eigener Mailserver muss nicht aus zwei Dutzend Containern bestehen. Stalwart packt den kompletten Mailserver – SMTP, IMAP, JMAP, Spam-Filter und Speicher – in einen einzigen, in Rust geschriebenen Container. Das macht ihn schlank, schnell und wartungsarm: die moderne, leichtgewichtige Alternative zu Schwergewichten wie Mailcow.

Mailserver bleiben anspruchsvoll – egal wie schlank

Stalwart ist einfacher aufzusetzen als klassische Stacks, nimmt dir aber die Kernaufgabe eines Mailserver-Betreibers nicht ab: Zustellbarkeit. Ob deine Mails ankommen oder im Spam landen, entscheiden SPF, DKIM, DMARC und ein sauberer Reverse-DNS-Eintrag – nicht die Software. Genau das behandelt das Tutorial zur E-Mail-Zustellbarkeit. Wer keine Lust auf diese Dauerpflege hat, fährt mit einem seriösen Mail-Hoster oft besser. Das ist eine ehrliche Abwägung, keine Schwäche.

Was bauen wir?

Am Ende läuft Stalwart 0.16.21 als einzelner Docker-Container auf deinem Server und stellt alles bereit, was ein vollwertiger Mailserver braucht:

  • SMTP: Annahme fremder Mails auf Port 25, Versand deiner Clients über Port 465,
  • IMAP (993) und das moderne JMAP für schnelle, effiziente Clients,
  • ManageSieve (4190) für serverseitige Filterregeln,
  • einen eingebauten Spam- und Phishing-Filter (kein separater Rspamd/ClamAV nötig),
  • einen integrierten Speicher (RocksDB) – keine externe Datenbank,
  • eine moderne Weboberfläche zur Verwaltung von Domains, Konten und Einstellungen.

Der große Unterschied zu Mailcow: Es ist ein Prozess, ein Container, wenige Hundert Megabyte Image. Das senkt RAM-Bedarf, Angriffsfläche und Wartungsaufwand deutlich. Getestet mit Docker 29 auf Debian 13.

Warum lohnt sich der schlanke Ansatz? Ein klassischer Mailserver-Stack besteht aus einem guten Dutzend Diensten – Postfix, Dovecot, Rspamd, ein Datenbankserver, ein Virenscanner, Redis, ein Webserver – die alle einzeln laufen, aktualisiert und aufeinander abgestimmt werden müssen. Jeder davon ist eine potenzielle Fehlerquelle und ein Stück Angriffsfläche. Stalwart bündelt dieselbe Funktionalität in einer einzigen, in Rust geschriebenen Anwendung. Rust bringt zudem Speichersicherheit von Haus aus mit – für eine Software, die ungefiltert Daten aus dem ganzen Internet entgegennimmt, ist das ein echtes Sicherheitsargument.

Voraussetzungen

  • Ein Server mit Debian 13 und installiertem Docker, auf dem die Mail-Ports 25, 465, 993 und 4190 frei sind. Dieses Rezept belegt zusätzlich Port 443, weil Stalwart sein Zertifikat selbst holt. Einen eigenen Server braucht es trotzdem nicht: Hat dein Reverse Proxy die 443 schon, zieht Stalwart daneben ein – wie, steht im Kasten in Schritt 4.
  • Eine Domain, deren DNS du selbst steuerst – für den A-Record des Mailservers und den MX-Record.
  • Ausgehendes SMTP muss offen sein. Viele Provider sperren es gegen Spam. Bei netcup macht das die Default-Policy „netcup Mail block" (Port 25/465/587) – die nimmst du dem Server im SCP selbst ab, ein Support-Ticket ist nicht nötig; siehe netcup-Firewall einrichten. Ohne offenen Port 25 kannst du keine Mails an fremde Server zustellen.
  • Ein PTR-/Reverse-DNS-Eintrag für die Server-IP (im netcup-SCP), der auf deinen Mail-Hostnamen zeigt.

Stalwart ist genügsam – für den Einstieg reicht einer der kleinen netcup-Tarife. Wie viel dein Setup insgesamt braucht, schätzt dir der Server-Rechner.

🍳 Empfehlung Anzeige

VPS 1000 G12.5

4 vCore · 8 GB RAM · 128 GB SSD

ab 14,50 €/Monat

Stalwart ist schlank – der VPS 1000 reicht für den Einstieg gut aus.

Zu netcup →

💶 1 Monat gratis:

Einmal einlösbar, gilt für VPS 1000 G12.5. Im leeren Warenkorb einlösen – der Code legt den Server selbst hinein. Im Warenkorb einlösen →

💶 5 € Gutschein für netcup-Neukunden: immer gültig · nicht für Domains und VPS Lite

Alle netcup-Gutscheine →

Schritt für Schritt

Schritt 1: DNS-Records anlegen

Richte zuerst die DNS-Einträge ein – sie brauchen Zeit zum Propagieren. DEINE_DOMAIN ist deine Mail-Domain, DEINE_SERVER_IP die IPv4-Adresse des Servers:

Ausgabe
mail.DEINE_DOMAIN.             A      DEINE_SERVER_IP
DEINE_DOMAIN.                  MX     10 mail.DEINE_DOMAIN.
autoconfig.DEINE_DOMAIN.       CNAME  mail.DEINE_DOMAIN.
autodiscover.DEINE_DOMAIN.     CNAME  mail.DEINE_DOMAIN.
mta-sts.DEINE_DOMAIN.          CNAME  mail.DEINE_DOMAIN.
ua-auto-config.DEINE_DOMAIN.   CNAME  mail.DEINE_DOMAIN.

Der MX-Record verweist andere Mailserver an mail.DEINE_DOMAIN. Dieser Hostname ist die Identität deines Servers. SPF, DKIM und DMARC ergänzt das Tutorial zur E-Mail-Zustellbarkeit – die DKIM-Schlüssel erzeugt Stalwart im Setup selbst.

Die vier CNAMEs sind nicht optional, auch wenn sie danach aussehen: Stalwart beantragt ein einziges Let’s-Encrypt-Zertifikat für alle fünf Hostnamen auf einmal. Fehlt einer davon im DNS, scheitert der komplette Zertifikatsauftrag – auch für mail.DEINE_DOMAIN. Nebenbei sind es genau die Namen, über die Mailprogramme später ihre Einstellungen automatisch finden (autoconfig/autodiscover). Wenn dein DNS-Anbieter keine CNAMEs auf dieser Ebene erlaubt, tun es vier A-Records auf DEINE_SERVER_IP genauso.

Schritt 2: Die compose.yaml schreiben

Lege einen Ordner an und wechsle hinein:

Terminal
mkdir -p /opt/stalwart && cd /opt/stalwart

Erstelle die Datei compose.yaml:

YAML
services:
  stalwart:
    image: stalwartlabs/stalwart:v0.16.21
    container_name: stalwart
    restart: unless-stopped
    ports:
      - "25:25"       # SMTP (Annahme von anderen Mailservern)
      - "465:465"     # SMTPS/Submission (Versand, implizites TLS)
      - "993:993"     # IMAPS
      - "4190:4190"   # ManageSieve
      - "8080:8080"   # Weboberfläche & JMAP (Ersteinrichtung)
      - "443:443"     # HTTPS (Konsole & JMAP nach der Einrichtung)
    volumes:
      - stalwart_config:/etc/stalwart
      - stalwart_data:/var/lib/stalwart
volumes:
  stalwart_config:
  stalwart_data:

Das Wichtigste: ein Service und zwei Volumes, die zusammen den kompletten Server ausmachen. In /etc/stalwart liegt nur eine winzige config.json, die auf den Datenspeicher zeigt – in /var/lib/stalwart steckt der eigentliche Inhalt: Einstellungen, Konten, Nachrichten und die DKIM-Schlüssel. Ein Volume auf einen anderen Pfad im Container zu legen bleibt wirkungslos – das Image schreibt ausschließlich in diese beiden Verzeichnisse. (Der Ordner /opt/stalwart auf dem Host von oben ist davon unabhängig: dort liegt nur deine compose.yaml.)

Stalwart holt sich sein TLS-Zertifikat später selbst per Let’s Encrypt – einen separaten Reverse Proxy brauchst du dafür nicht. Achte darauf, dass Port 443 auf dem Host frei ist (Stalwart nutzt ihn auch für den Zertifikatsabruf, siehe Schritt 4).

Warum kein Port 587 und 143?

Viele Anleitungen mappen zusätzlich 587 (Submission mit STARTTLS) und 143 (IMAP ohne TLS). Stalwart legt für diese beiden Ports von Haus aus keinen Listener an – ein Mapping würde also ins Leere zeigen. Standardmäßig lauschen genau sieben Dienste: smtp (25), submissions (465), imaps (993), pop3s (995), sieve (4190), http (8080) und https (443). Wer 587 oder 143 wirklich braucht, legt den Listener in der Konsole unter Settings → Network → Listeners an und ergänzt das Port-Mapping.

Schritt 3: Den Container starten und das Startpasswort holen

Starte Stalwart:

Terminal
docker compose up -d

Beim allerersten Start läuft Stalwart im Bootstrap-Modus: Es gibt noch keine Konfiguration, und Port 8080 ist für die Ersteinrichtung offen. Dabei erzeugt es ein einmaliges Administrator-Passwort, das du aus den Logs abliest:

Terminal
docker compose logs | grep -A4 "temporary administrator"
Ausgabe
stalwart  | 🔑 Stalwart bootstrap mode - temporary administrator account
stalwart  |
stalwart  |    username: admin
stalwart  |    password: <EINMAL-PASSWORT>

Benutzername und Passwort stehen zwei bzw. drei Zeilen unter der Überschrift – deshalb -A4 und nicht weniger. Notiere das Passwort, es wird nur einmal angezeigt. (Wenn du lieber ein festes Passwort setzt, kannst du in der compose.yaml unter environment: ein STALWART_RECOVERY_ADMIN=admin:DEIN_PASSWORT hinterlegen.)

Schritt 4: Anmelden und den Einrichtungs-Assistenten durchlaufen

Rufe die Weboberfläche im Browser auf: http://DEINE_SERVER_IP:8080/admin. Du landest auf der Anmeldung. Melde dich als Benutzer admin mit dem Einmal-Passwort aus Schritt 3 an – die Eingabe erfolgt in zwei Schritten (erst Benutzername, dann Passwort):

Die Anmeldemaske der Stalwart-Weboberfläche mit Feld für den Benutzernamen.
Der Login der Stalwart-Weboberfläche.

Nach der Anmeldung begrüßt dich der Einrichtungs-Assistent. Im ersten Schritt legst du die Server-Identität fest:

  • Server Hostname: mail.DEINE_DOMAIN – der FQDN aus deinem A-Record.
  • Default Email Domain: DEINE_DOMAIN – deine Mail-Domain.
  • Automatically Obtain TLS Certificate aktiviert lassen – Stalwart holt das Let’s-Encrypt-Zertifikat selbst. Dafür muss Port 443 von außen erreichbar sein: Stalwart nutzt standardmäßig die TLS-ALPN-01-Challenge über 443, Port 80 braucht es dafür nicht.
  • Generate Email Signing Keys aktiviert lassen – das erzeugt gleich deine DKIM-Schlüssel.

Der Ersteinrichtungs-Assistent von Stalwart mit den Feldern für Server-Hostname und Standard-Domain.
Schritt 1 des Assistenten: die Server-Identität.

Klick dich durch die weiteren Schritte des Assistenten:

  • Speicher (Storage): Die Voreinstellung RocksDB ist ein eingebetteter Schlüssel-Wert-Speicher und für Einzelserver-Setups perfekt – kein externer Datenbankserver nötig. Nur für große, geclusterte Installationen greifst du zu PostgreSQL o. Ä.
  • Verzeichnis (Directory): Das interne Verzeichnis verwaltet Konten und Passwörter direkt in Stalwart. Wer bereits ein zentrales LDAP/Active Directory betreibt, kann es hier stattdessen anbinden – für den Einstieg bleibst du beim internen Verzeichnis.
  • Logging: Stell Log Destination auf Console um. Die Voreinstellung Log file schreibt in eine Datei im Container, die im Docker-Betrieb niemand zu Gesicht bekommt – danach bliebe docker compose logs für immer leer. Mit Console landet alles dort, wo du es erwartest. Beim Logging level ist Info im Alltag ein guter Kompromiss; bei Problemen drehst du kurzzeitig auf Debug.
  • DNS: Für den Anfang genügt die manuelle Verwaltung – die anzulegenden Records zeigt dir Stalwart später unter der jeweiligen Domain an.

Zum Abschluss erzeugt Stalwart dein dauerhaftes Administrator-Konto und zeigt Adresse und Passwort ein einziges Mal an – schreib beides sofort weg. Der Benutzername ist ab jetzt die volle Adresse admin@DEINE_DOMAIN, nicht mehr das kurze admin aus dem Bootstrap-Modus.

Die letzte Meldung des Assistenten ist leicht zu überlesen und trotzdem entscheidend: Stalwart muss neu starten, damit die frisch geschriebene Konfiguration greift.

Terminal
docker compose restart

Danach ist der Bootstrap-Modus beendet, und die Konsole antwortet zusätzlich per HTTPS auf Port 443. Der HTTP-Listener auf 8080 bleibt bestehen – praktisch hinter einem Reverse Proxy, aber ein Grund mehr, ihn nicht ungeschützt ins Internet zu hängen.

Schon ein Reverse Proxy im Einsatz?

Anders als klassische Mailserver kann Stalwart seine Weboberfläche problemlos hinter einem bestehenden Traefik laufen – route dann einfach den HTTP-Port 8080 dorthin. Die Mail-Ports (25, 465, 993, 4190) müssen weiterhin direkt am Server anliegen, denn sie sprechen kein HTTP und lassen sich nicht über einen HTTP-Proxy leiten.

Belegt der Proxy bereits Port 443, kann Stalwart sein Zertifikat nicht mehr selbst per TLS-ALPN-01 holen. Von Hand nachlegen musst du trotzdem nichts: Lass Traefik das Zertifikat holen wie bisher und gib es an Stalwart weiter – ein traefik-certs-dumper schreibt Zertifikat und Schlüssel aus acme.json in ein gemeinsames Volume, Stalwart liest sie als Datei. Den Weg beschreibt Stalwart oder Mailcow? Schritt für Schritt; wir haben ihn nachgebaut, und Stalwart liefert danach auf 993 und 465 dasselbe Let’s-Encrypt-Zertifikat aus, das Traefik für die Weboberfläche nutzt.

Schritt 5: Domain und erstes Postfach anlegen

Melde dich nach dem Neustart mit admin@DEINE_DOMAIN an – du landest direkt in der Verwaltungskonsole. Weitere Domains legst du in der linken Navigation unter Domains → Domains an, die Postfächer unter Directory → Accounts:

Die Stalwart-Verwaltungskonsole mit der Kontenübersicht.
Die Verwaltungskonsole: Konten verwalten.

Über Create user legst du ein Postfach an – Benutzername (der lokale Teil vor dem @), Domain, angezeigter Name und unter Authentication ein starkes Passwort (Passwortmanager!). Dieses Konto kann sich anschließend per IMAP/JMAP und SMTP anmelden:

Das Formular zum Anlegen eines neuen Postfachs in Stalwart.
Ein neues Postfach anlegen.

Schritt 6: In einem Mailprogramm einrichten

Trage das neue Konto in deinem Mailprogramm ein. Stalwart unterstützt Autodiscovery, meist reicht also E-Mail-Adresse und Passwort. Manuell nutzt du:

Ausgabe
IMAP:        mail.DEINE_DOMAIN, Port 993, SSL/TLS
SMTP:        mail.DEINE_DOMAIN, Port 465, SSL/TLS
Benutzer:    die volle E-Mail-Adresse

Beide Ports nutzen implizites TLS: Die Verbindung ist von der ersten Sekunde an verschlüsselt. Wenn dein Mailprogramm hartnäckig Port 587 mit STARTTLS vorschlägt, stell es von Hand auf 465 um – den Submission-Listener auf 587 bringt Stalwart nicht mit (siehe Schritt 2).

Neben dem altbewährten IMAP spricht Stalwart auch JMAP – ein modernes, JSON-basiertes Protokoll, das für heutige Netze entworfen wurde. JMAP überträgt nur echte Änderungen statt ganze Ordner neu zu synchronisieren, kommt mit einer einzigen Verbindung aus und ist damit spürbar sparsamer mit Akku und Datenvolumen – gerade auf dem Handy. Unterstützt dein Mail-Client JMAP (z. B. die Thunderbird-Familie in neueren Versionen), profitierst du direkt davon; ansonsten bleibst du bei IMAP, das genauso funktioniert.

Eine Mail von dir an dich selbst sollte sofort im Posteingang landen – das beweist, dass lokale Zustellung, IMAP und SMTP stehen. Der Härtetest ist aber das Senden nach außen und der Empfang von außen, und da entscheidet die Zustellbarkeit.

Hinweis

Prüfe deine Zustellbarkeit nach dem Setup mit einem Dienst wie mail-tester.com: Er bewertet SPF, DKIM, DMARC und Reverse DNS. Wie du auf die volle Punktzahl kommst, ist Thema des Tutorials zur E-Mail-Zustellbarkeit.

Schritt 7: Spam-Filter und Sieve-Regeln

Ein großer Vorteil von Stalwart: Der Spam- und Phishing-Filter ist bereits eingebaut und aktiv – du musst keinen separaten Rspamd-Container betreiben und pflegen. Er bewertet eingehende Mails anhand zahlreicher Merkmale (Reputation, SPF/DKIM/DMARC-Ergebnis, Inhaltsheuristiken) und markiert oder blockiert Verdächtiges. Die Einstellungen dazu liegen in einem eigenen Bereich der Konsole: Über das Zahnrad-Symbol unten links wechselst du von Management zu Settings, dort findest du Spam Filter. Hier passt du die Empfindlichkeit an und setzt Absender auf Allow- oder Blocklisten.

Für eigene Regeln beim Ein- und Ausgang unterstützt Stalwart Sieve – die standardisierte Filtersprache. Damit sortierst du z. B. Newsletter automatisch in einen Ordner oder leitest bestimmte Absender weiter. Sieve-Skripte verwaltest du serverseitig (über ManageSieve auf Port 4190) oder direkt in der Weboberfläche, sodass die Regeln unabhängig vom Mailprogramm greifen – auch dann, wenn dein Rechner aus ist.

Tipp

Weil der Filter serverseitig arbeitet, gilt er für alle deine Geräte gleichzeitig. Eine einmal angelegte Sieve-Regel oder eine Spam-Entscheidung wirkt am Handy genauso wie am Laptop – anders als bei clientseitigen Filtern, die du auf jedem Gerät neu einrichten müsstest.

Wenn es nicht funktioniert

Die Weboberfläche auf Port 8080 antwortet nicht. Der Container ist noch am Hochfahren oder Port 8080 ist belegt/geblockt. docker compose ps prüfen, docker compose logs lesen und sicherstellen, dass die Firewall Port 8080 (und später 443) durchlässt. Bleibt die Log-Ausgabe nach dem Setup komplett leer, steht das Log-Ziel noch auf Log file – in der Konsole unter Settings → Telemetry → Tracers auf Console umstellen und neu starten.

Ich habe das Bootstrap-Passwort verpasst. Es wird nur einmal geloggt. Setze in der compose.yaml ein STALWART_RECOVERY_ADMIN=admin:DEIN_PASSWORT unter environment: und starte mit docker compose up -d neu – damit hast du ein festes Recovery-Admin-Konto.

Kein TLS-Zertifikat, die HTTPS-Adresse zeigt eine Warnung. Entweder erreicht Let’s Encrypt deinen Server nicht auf Port 443 (Stalwart nutzt die TLS-ALPN-01-Challenge über 443), oder einer der fünf Hostnamen aus Schritt 1 fehlt im DNS. Das Log nennt den Schuldigen beim Namen: ACME authentication error … NXDOMAIN looking up A for autoconfig.DEINE_DOMAIN. Fehlende Records nachtragen, Port 443 in der Firewall öffnen – Stalwart wiederholt die Zertifikatsanforderung danach automatisch.

Mails nach außen bleiben hängen, Logs zeigen Timeouts auf Port 25. Dein Provider sperrt ausgehenden SMTP-Verkehr. Bei netcup ist die Default-Policy „netcup Mail block" (Port 25/465/587) schuld: Im SCP unter Firewall → Policys dem Server dieses netcup-Template abnehmen – kein Ticket nötig, siehe netcup-Firewall einrichten. Ohne das ist keine Zustellung an fremde Server möglich.

Andere Server nehmen deine Mails nicht an oder sie landen im Spam. Fehlender oder falscher PTR-Eintrag, kein SPF/DKIM/DMARC. Das ist kein Fehler von Stalwart, sondern Sache der DNS-/Reputations-Konfiguration – siehe das Tutorial zur E-Mail-Zustellbarkeit.

Dein Problem ist nicht dabei? Alle Fehlermeldungen durchsuchen →

Wartung & Backups

Updates. Stalwart ist ein einzelner Container – ein Update ist entsprechend einfach:

Terminal
cd /opt/stalwart
docker compose pull && docker compose up -d

Lies vor größeren Sprüngen die Release-Notes auf GitHub; bleib bei einem konkreten Versions-Tag (wie hier v0.16.21) statt latest, damit Updates reproduzierbar bleiben. Stalwart veröffentlicht im Wochenrhythmus – du musst nicht jeden Patch mitnehmen, solltest aber nicht monatelang stehenbleiben.

Backups. Alle Daten – Nachrichten, Konten, Einstellungen und die DKIM-Schlüssel – liegen im Volume stalwart_data (/var/lib/stalwart); stalwart_config enthält nur die kleine config.json. Sichere beide Volumes regelmäßig weg vom Server, am saubersten verschlüsselt mit restic. Weil Stalwart die Daten im laufenden Betrieb schreibt, sicherst du am konsistentesten, indem du den Container kurz stoppst (docker compose stop), die Volumes sicherst und wieder startest. Die DKIM-Schlüssel sind besonders wichtig: Gehen sie verloren, brechen nach einer Wiederherstellung deine Signaturen, bis du die DNS-Records neu setzt. Ein Backup, das du nie zurückgespielt hast, ist nur ein Hoffnungswert – teste die Wiederherstellung einmal auf einem Testsystem.

Reputation im Blick behalten. Prüfe gelegentlich, ob deine Server-IP auf einer Blockliste gelandet ist, und wirf einen Blick in die Stalwart-Konsole unter Observability. Ein kompromittiertes Postfach, das Spam verschickt, ruiniert die Reputation deiner ganzen Domain schnell.

Zuletzt aktualisiert: 02.10.2026

Feedback per E-Mail: feedback@serverkueche.de

Wie geht's weiter?

Das könnte dir auch schmecken