Work down this before you publish an MX record that real people depend on. Each item has a command that either passes or does not — nothing here relies on believing the configuration is right.
JWT_SECRET changed from the default and generated randomly. Anyone who knows it can mint a session for any account.
DELIVERY_TRANSPORT is not console. The default delivers nothing.
sh
grep DELIVERY_TRANSPORT .env
SIGNUPS=closed unless you intend to host mail for strangers.
TRUSTED_PROXIES set if anything sits in front of the HTTP port. Without it every request looks like 127.0.0.1 and the rate limiter treats the internet as one client.
PUBLIC_URL is the real HTTPS URL. It goes into password reset and verification emails.
Ports are the real ones — 25, 587, 465, 143, 993, 110, 995 — and the binary can bind them.
sh
sudo ss -lntp | grep bun
.env is mode 600 and owned by the service user. It holds the database password, the JWT secret, and your storage keys.
Bucket configured if you expect any volume. Without one, bodies go through the WAL.
Bucket is private. Objects are written with no ACL and inherit the bucket default. Check it, especially on a bucket you already use for something else.
sh
curl -sI "https://BUCKET.REGION.digitaloceanspaces.com/corsair/..." | head -1
A 403 is correct. A 200 means your mail is public.
Someone other than you can find the runbook. Where the backups are, how to restart it, and who to call about the IP. Self-hosted mail has a bus factor of one by default.