Mail is the record of the business itself. Correspondence, contracts, history — all of it piles up there. Rather than leave it parked on another company's server, take back control of the inbox to your own side.
But mail is also a domain to be honest about. Receiving is easy; sending (deliverability) is hard. This chapter stands it up with that line drawn clearly.
Why keep mail on your own side
- Control of the record — retention, search, and export of past mail by your own rules
- Step off per-seat billing — the monthly bill doesn't stack with mailbox count
- One with the gate — align accounts with the 2-03 authentication
Stand up Stalwart
The mail server is Stalwart. A Rust single server carries SMTP, IMAP, JMAP, spam defense, and DKIM signing. A replacement for Exchange. Storage can be pointed at the PostgreSQL from 2-02.
# compose.yaml — stand up a single mail server
services:
mail:
image: stalwartlabs/mail-server:latest
volumes: ["./stalwart:/opt/stalwart-mail"]
ports: ["25:25", "587:587", "465:465", "993:993", "8080:8080"]
restart: always
In the admin UI (:8080), create the domain and mailboxes. No code written.
Get the DNS right — MX, SPF, DKIM, DMARC
With mail, the DNS is the real body of the work, more than the server. Set these four correctly.
example.com. MX 10 mail.example.com.
example.com. TXT "v=spf1 mx -all"
default._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=...(generated by Stalwart)"
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"
Set the reverse record (PTR) for the server's IP as well. Miss this, and the mail you send does not reach anyone.
Outbound deliverability — the honest part
Direct sending from a self-hosted server is at the mercy of IP reputation, blocklists, and each provider's judgment — and sometimes it does not arrive. This is not about OSS being inferior; it is the reality of how mail works.
So the realistic design is this:
- Receiving, storage, search — owned by your Stalwart (this is the real body of control)
- Outbound sending — go through an authenticated SMTP relay (a send-only service)
The relay is a thin layer borrowing only sending deliverability; the mailbox itself stays on your side. Separate where you hold control from where you borrow deliverability — that is the honest, durable way.
"All in-house" is not always the right answer for mail. The inbox on your side, the sending deliverability borrowed — stand it up with the line drawn.
The client — Thunderbird
Reading and writing work with any client that speaks IMAP / JMAP. Thunderbird is free and runs the same on Windows, Mac, and Linux. Phones connect with the stock mail app over JMAP / IMAP.
Migration — from Microsoft 365
Existing mail moves with imapsync, which syncs one IMAP store wholesale into another.
imapsync --host1 outlook.office365.com --user1 you@old \
--host2 mail.example.com --user2 you@new
No need to cut over at once. Receive on both for a while, set forwarding, run in parallel, then point the MX at Stalwart once settled (2-09).
Retention and safety — a few lines of rules
Mail retention needs no dedicated archive product. All the mail already sits in the 2-02 PostgreSQL, and it is already inside the 2-01 rule "protect the data and the spec." How many years to keep is one line in the business-rules Markdown — and that is the entire retention spec.
The safety side is one line too. Never open executable attachments. Spam is handled by Stalwart's built-in filter. For a suspicious mail, have the AI read the body before any attachment is opened, as input to your judgment.
Migration, by the way, is the same from Gmail — imapsync connects IMAP to IMAP, and it does not care whether the far side is Microsoft or Google.
Summary
The inbox, on your own side.
- Stalwart — SMTP, IMAP, JMAP, spam defense, DKIM in one server (on the 2-02 PostgreSQL)
- DNS (MX, SPF, DKIM, DMARC, PTR) — the real body of mail is here
- Lean on a relay for sending — inbox yours, deliverability borrowed, line drawn
- Thunderbird — a free client, identical across OSes
- imapsync — migrate from Microsoft 365 in parallel, point the MX last
Next, we stand up meetings and booking (Jitsi, Cal.com) and bring Teams and the booking services to our own side.