Mail server
Self-hosted mail for my own domain, run as a single Stalwart binary behind Caddy
The problem
I wanted mail I actually control: my own domain, mailboxes organised the way I like them, and a server my own code can send through without signing up for somebody's API. It is also just nice to be able to say "write me at hello@sallabergerjulian.com". Sending is the easy half, though. Whether anyone accepts your mail is decided by your DNS records, your TLS and how the server behaves — and mine runs on Windows, where Stalwart's defaults quietly assume Linux.
The approach
Stalwart runs as a native Windows service behind Caddy, with no container and no mail suite in between. The domain publishes SPF with a hard fail, DKIM signatures in both RSA and Ed25519, DMARC and TLS reporting, and every mail port speaks TLS 1.3. Caddy renews the certificate but Stalwart only reads it at load, so a scheduled script compares the file's hash every night and triggers a reload that drops no connections. A second script checks the service, the certificate's remaining lifetime, four blocklists and free disk space once a week and mails me the result — over hand-written SMTP, because PowerShell's built-in mail command cannot talk to an implicit-TLS port.
The result
In service since August 2026 for three mailboxes, and Gmail accepts what it sends. Over one month it took in 57 real messages and turned away about 1,900 bot handshakes and 1,100 login attempts on port 25 before any of them became mail. The weekly check also confirms that today's log file is actually being written, because logging once pointed at a Unix path and stayed silent for 17 hours while the service looked perfectly healthy.
What mattered
- Two DKIM algorithms side by side, RSA and Ed25519
- Certificate renewals reach the mail server through a reload, not a restart
- No open relay, and no authentication offered on port 25 at all