Skip to content

ADR 0001 — No self-hosted email

  • Status: Accepted
  • Date: 2026-04-16 (consolidated from the compose comment block and docker/mailserver/README.md)

Context

The stack considered running a docker-mailserver container for mail.h5h.me and transactional email (Authentik password resets, alerts).

Decision

Don't. The homelab does not host its own mail.

Reasoning

  1. SMTP/IMAP need direct TCP. Cloudflare Tunnel only proxies HTTP(S) — so SMTP (25/465/587) and IMAP (143/993) cannot ride the tunnel. Hosting mail means opening real ports on the LAN, which breaks the "zero LAN exposure" invariant.
  2. Residential ISPs block outbound 25. Even if the LAN were willing, the upstream ISP rejects outbound SMTP, so outgoing mail won't deliver.
  3. Static IP + rDNS required for deliverability. The host has neither. Mail sent from dynamic residential IPs is rejected or spam-filed by every major provider.
  4. Operational cost is high. Mail servers need SPF / DKIM / DMARC, rotation, anti-spam, certificate management, and reputation babysitting. The value doesn't justify the ongoing cost.

Alternatives adopted

  • Receive: Cloudflare Email Routing (hemanth@h5h.me → personal mailbox like ProtonMail/Fastmail).
  • Send (transactional): external SMTP relay — Brevo (300/day free), Mailgun, SendGrid. Placeholders exist in docker/.env.example (SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD).

Consequences

  • docker/mailserver/ directory is kept intentionally empty (as a pointer to this ADR). Deleting it would lose the decision trail.
  • apps/dashboard/src/App.jsx still lists "Email" at mail.h5h.me — that's a stale UI element, tracked in known_issues.md #9.
  • If the stack ever migrates to a VPS with a static IP and clean rDNS, revisit this ADR.

MIT License