Back to Blog
2 min read

Pinning a Mail Deployment and Managing Mailbox Imports with systemd

Pinning the Deployment

I pinned the TinyCLD mail deployment (1bb01692) so the deployed version is reproducible instead of tracking a moving target. I followed it with a series of deployment hardening changes, all mirrored between the platform repo and the mail-deploy repo.

Persistent State and Compose Identity

I moved server state to persistent paths (6c0b647e) so a redeploy doesn’t discard data, made the deployment scripts executable (a2697a51), and retained the Compose project identity (d8111e67). Project identity sounds trivial until a redeploy creates a parallel stack with a new name and orphans every volume—keeping the name stable is what makes “up” actually replace the previous stack.

Health Waits and Build Context

I made the deployment wait for TinyCLD health (8cabaf45) instead of racing ahead while the service was still starting. I also pinned the server build context (9287a063) so the image builds from a deliberate directory rather than whatever happens to be nearby.

Managing Imports with systemd

I moved mailbox imports under systemd (00f5ef8f) so they run reliably outside the deploy process. Importing mail is long-running and needs retries, logging, and a unit that survives a deploy. Then I bounded Go memory during mailbox imports (51439d8d)—an unbounded importer will happily consume all available memory on a large mailbox.

Admin Visibility

I exposed personal mailbox metadata to admins (26533934) so they can see what’s been imported and diagnose problems without shelling into the server.

Why Mail Is Hard

Mail is a pile of standards with decades of edge cases, and a self-hosted stack has to handle them all. Today’s commits are the foundation: a reproducible deployment, persistent state, and bounded resource use. The ugly edge cases come next.

Newer post

A Continuous Microsoft 365 IMAP Bridge and the Mail Edge Cases

Older post

A Name Fix and a Temporary Caela Mention