How to Back Up a Self-Hosted Mail Server (Before You Need To)

The short answer
Back up five things: the mail store, the user and alias database, Dovecot control files, DKIM private keys and TLS material, and every config file. Copy them off the box, encrypted. Test by restoring to a throwaway VM, logging in over IMAP, and checking message counts and UIDs. Quarterly at minimum.
How to back up a self hosted mail server: what to copy, why DKIM keys and Dovecot control files matter, and how to test the restore first.
On this page
- 01The short answer
- 02What actually has to be backed up
- 03Why Dovecot control files are the part people miss
- 04Before you start
- 05How to back up a self-hosted mail server, step by step
- 06Should you back up DKIM private keys?
- 07Platform differences
- 08How to test a mail server restore, and how often
- 09What to do when the restore doesn't work
- 10A faster way to survive the outage itself
Most advice on how to back up a self hosted mail server stops at "rsync your Maildir somewhere". That copies the messages and loses the things that make them usable: the UID mapping every IMAP client depends on, the DKIM key your domain signs with, and the config that tells Postfix and Dovecot what any of it means.
This is the runnable version — what to copy, what is safe to regenerate instead, and how to prove the restore works while it is still a drill.
The short answer#
A mail server backup is five things that usually live in five places. Copy all five, encrypt them, and send them somewhere the mail server itself cannot delete.
Then restore them onto a throwaway VM and log in over IMAP. A backup you have never restored is a hypothesis.
- The mail store, with file timestamps preserved.
- The user database: accounts, password hashes, aliases, forwarding.
- Dovecot control files, which sit inside the mail store and are not rebuildable.
- Secrets: DKIM private keys, TLS certificates, the ACME account key.
- Configuration, including whatever you edited by hand at 2am and never wrote down.
- Not the mail queue: restoring an old one re-delivers mail that already went out.
What actually has to be backed up#
Sort it by what happens if it is missing. The paths below are common defaults — check your own config, because every distribution moves at least one.

| Component | Typical location | If you lose it | Rebuildable? |
|---|---|---|---|
| Mail store (Maildir, mdbox) | /var/vmail, ~/Maildir | The mail is gone | No |
| Control files (dovecot-uidlist, dovecot-keywords) | Inside each Maildir | New UIDs; clients re-download everything | Not safely |
| Index files (dovecot.index*) | Maildir, or mail_index_path | A slower first open | Yes |
| Users and aliases | SQL database, /etc/dovecot/users | Nobody can log in; mail bounces | By hand only |
| DKIM private keys | /etc/opendkim/keys, rspamd, mailcow crypt volume | Signing breaks until you publish a new selector | Yes, via DNS |
| TLS and ACME account key | /etc/letsencrypt | Reissue, subject to rate limits | Yes |
| Configuration | /etc/postfix, /etc/dovecot, mailcow.conf | A rebuild from memory, which is where the real downtime lives | Painfully |
Why Dovecot control files are the part people miss#
Dovecot's Maildir documentation draws a hard line between two kinds of metadata sitting in the same directory. Index files are disposable: "Index files can be deleted and rebuilt without any side effects." Control files are not — "if you delete control files you'll cause messages to get new UIDs and possibly lose keyword names."
dovecot-uidlist maps IMAP UIDs to Maildir filenames. When UIDs change, the docs note, clients invalidate their cache and download everything again — for every user at once, that turns a clean restore into a self-inflicted load spike.
Copy the whole Maildir, not just the mail
Before you start#
- Decide your RPO and RTO in plain numbers. "We can lose an hour of mail and be back in four" drives a different design than "we can lose a day".
- Preserve timestamps. Dovecot treats a message file's mtime as the IMAP INTERNALDATE and says it must never change, so use rsync -a, never a plain cp.
- Give the backup target its own credentials. If the mail server can delete its own backups, so can whoever compromises the mail server.
- Dump databases rather than copying their files hot. mysqldump or pg_dump gives a consistent dump; a file copy of a running database is a coin flip.
- Find where mail actually lives first. Dovecot 2.4 replaced the old mail_location setting with mail_driver plus mail_path, so a guide written for 2.3 points at a setting your config no longer has.
How to back up a self-hosted mail server, step by step#
- 1
Inventory the box
Write down the mail path, the user database, the DKIM key directory, the certificate directory and every config file you have edited. That list is the backup job.
- 2
Dump what cannot be copied hot
mysqldump or pg_dump for users and aliases; trigger a Redis save before copying its dump. Write the output into a staging directory the file copy then picks up.
- 3
Copy the mail store with attributes intact
rsync -aH preserves timestamps, permissions and hard links; mailcow's docs use rsync -aH --delete against the Docker volumes. Do not rsync mail to a Samba share — permissions will not survive.
- 4
Export the secrets separately, encrypted
DKIM private keys and /etc/letsencrypt, including the ACME account key, belong in an encrypted archive with its own retention policy.
- 5
Capture configuration as text
Put /etc/postfix, /etc/dovecot, mailcow.conf and your DNS records in a private git repository. Diffs answer what a tarball cannot: what changed since it last worked.
- 6
Send it off the box
Push to object storage or a second host with versioning or append-only mode on, so server access alone cannot rewrite the backup history.
- 7
Automate it, and alert on failure only
mailcow's docs publish a nightly cron line with --delete-days for retention. Wrap yours to mail you only on a non-zero exit code, or you will stop reading the success mail within a week.
- 8
Write the runbook somewhere off the server
Commands, credential locations, DNS records, expected message counts. If it only exists on the machine that died, it does not exist.
Should you back up DKIM private keys?#
Yes — as secrets rather than as data. They are also the one irreplaceable-looking item on the list that is genuinely replaceable.
DKIM publishes the public half in DNS under a selector. RFC 6376 section 3.1 describes selectors as the mechanism for replacing public keys on a routine basis, by advertising both keys during a transition window. Lose a private key and you can generate a new one, publish it under a new selector, and sign again.
What that costs is time you will not have: inventing a key, editing DNS and waiting on TTLs mid-outage. If your domain publishes a DMARC policy of quarantine or reject and SPF does not align on that path, unsigned mail is handled accordingly meanwhile. DMARC's current spec is RFC 9989, published May 2026, which obsoletes RFC 7489.
One rule survives any restore: do not reuse an old selector for a new key. RFC 6376's operations note says reuse "makes it impossible to tell the difference between a message that didn't verify because the key is no longer valid and a message that is actually forged".
An unencrypted DKIM key in a backup is a forgery kit
Platform differences#
The components are the same everywhere; what differs is how much work the stack has already done for you. Dovecot's own mailbox-level tool is the one that bites: doveadm backup is one-way, and "If there are any changes in the destination they will be reverted". doveadm sync is the two-way variant, which "merges all changes without losing anything".
| Stack | Built-in backup | What it covers | The catch |
|---|---|---|---|
| mailcow (Docker) | helper-scripts/backup_and_restore.sh | vmail, crypt, redis, rspamd, postfix, mysql, or all | The docs say not to copy the script elsewhere, and restoring needs mailcow initialised and running on the target first |
| Postfix + Dovecot, hand-rolled | None | Whatever you script | You own the consistency problem: dump SQL, then copy files |
| Dovecot, mailbox level | doveadm backup / doveadm sync | Mailboxes per user, including across formats | doveadm backup is destructive to the destination |
| Mailu, iRedMail, Mail-in-a-Box | Varies by project | Varies by project | Read that project's docs for what its backup command includes; assume nothing here transfers |
Direction is the whole risk
How to test a mail server restore, and how often#
Restore to a fresh VM with no DNS pointed at it. Bring the stack up, restore the database dump, restore the mail store, then connect a normal IMAP client and log in as a real user.
Check three things: message counts per folder against the live server, that UIDs did not change, and that a test send is signed and accepted. If UIDs moved, your control files did not make it into the backup.
Quarterly is a reasonable floor, plus a test after any change to the mail path, the storage layout or the backup script — those are the changes that silently break a job which keeps reporting success.
What to do when the restore doesn't work#
Failed restores fail in a small number of recognisable ways, and the symptom usually names the missing piece.
| Symptom | Likely cause | Fix |
|---|---|---|
| Every client re-downloads the whole mailbox | dovecot-uidlist missing, so UIDs were reassigned | Restore control files from an older backup; otherwise let it resync and stagger users to spread the I/O |
| Mail files on disk, mailbox looks empty | Mail path differs between old and new host | mailcow's docs flag a MAILDIR_SUB mismatch between old and new mailcow.conf as a case where no mail is displayed |
| Message files exist but are unreadable | Encrypted storage restored without its keys | mailcow's mail crypt docs put the keypair in the crypt volume, so a vmail-only backup restores ciphertext. Restore crypt too |
| Spam filter state refuses to restore | Architecture mismatch | mailcow's restore docs mark rspamd data from another architecture, x86 to ARM64, incompatible and skip it. Retrain instead |
| Mail sends but fails DKIM at the recipient | Key restored under a selector DNS no longer publishes | Publish that selector's public key, or generate a new key under a new selector |
| Certificate renewal fails after restore | Rate limit hit while retrying issuance | Restore /etc/letsencrypt with the account key. Let's Encrypt documented 50 certificates per registered domain and 5 per identifier set every 7 days, as of 5 August 2026 |
A faster way to survive the outage itself#
None of the above gets shorter because of software. The backup is the server operator's job, and we will not pretend otherwise: AI Emaily is an email client, not a mail server and not a backup product, and it is no substitute for the restore drill above.
What it changes is the hours in between. AI Emaily connects any IMAP and SMTP mailbox alongside Gmail and Outlook accounts, so a self-hosted domain is one account among several rather than the only place your mail exists. During a restore that means working from a fallback address in the same inbox, and searching across accounts to check what actually came back.
The limit, stated plainly: a client's copy is a convenience, not an archive, and your own export lives at /docs/account-data. We build AI Emaily, so read this as the one interested paragraph on the page.
Frequently asked
See it in AI Emaily
Keep reading
Sources

Written by
Nafiul HasanNafiul Hasan is an entrepreneur and AI automation system builder with 10+ years of experience turning messy, manual workflows into reliable automated systems. He designs and ships AI enterprise solutions end-to-end — the agent logic, the data plumbing, and the product people actually use — and founded AI Emaily to give busy professionals their attention back. He writes here from the builder's seat: what works, what breaks, and how to put AI to work without giving up control.