Dovecot mailbox backups
Feb 05, 2020 dovecot linux restic
I've been using the same provider for my web and email hosting for a number of years. For a variety of reasons (the main one being increases in price vs what I can achieve on AWS), I've been working to move away from them. This website is already hosted on S3 - I don't have any other website needs that aren't met right now. That just leaves my email.
To facilitate this - I wondered "how hard can it be to run a mailserver for a couple of domains and a handful of users?". Well, I now have a mailserver running Postfix and Dovecot, and a handful of plugins - there's plenty of guides around doing this, such as this one. One area I had a hard time figuring out was how to do mailbox backups for all users. I'm using virtual mailboxes, so no actual users on the mailserver.
My goal here was to use restic for backups - I'm using it for other backups already. First thought was to just target the mail storage directory directly with restic to backup, but apparently you shouldn't do that - especially when using the mdbox format - as the indexes may change halfway through and the backup be corrupted. Instead it's safer to use
doveadm to sync the mailbox elsewhere, then backup that.
So - first job, backing up all the mailboxes. Seems straightforward enough using
doveadm backup, right? It even has an option to iterate all users:
doveadm backup -A maildir:/var/backups/mail/mailboxes/
Nope - when you use
-A to iterate over all users, it literally runs the backup for each user one after the other, all of them overwriting the others in the target directory. Ok... so the docs say that the
maildir is the same as the
mail_location setting. That allows you to use
%n as placeholders for user name, domain and name respectively - let's try that:
doveadm backup -A maildir:/var/backups/mail/mailboxes/%u
Nope again! Now you just get a directory called
%u, with the same each-user-overwriting-the-previous-one problem (
%n have the same issue, before you try). I spent a good amount of time looking around to see if there was a way to get the backup working with
-A into separate directories, but just couldn't find one. At this point I figured it was probably best to just script around it.
First up - let's get a list of users:
doveadm user *@*
Works for me - get one user per line in the output. Now to do something useful with it:
doveadm user *@* | while read user; do echo Backing up mail for $user doveadm backup -u $user maildir:/var/backups/mail/mailboxes/$user done
Perfect! I also scripted the dumping of the database holding the config for the virtual domains/users, and added the restic backup part after initialising the repository. Here's my complete
#!/usr/bin/bash echo Backing up database rm -f /var/backups/mail/db/dump.sql mkdir -p /var/backups/mail/db mysqldump -p<SQL PASSWORD> postfix > /var/backups/mail/db/dump.sql doveadm user *@* | while read user ; do echo Backing up mail for $user doveadm backup -u $user maildir:/var/backups/mail/mailboxes/$user done export RESTIC_PASSWORD="<RESTIC PASSWORD>" restic -r s3:s3.amazonaws.com/<MYBUCKET>/restic/mailserverdata backup /var/backups/mail export RESTIC_PASSWORD="x"
Side note: if anyone has a way to pass in the repository password to restic on the command line rather than having to set it in the environment, I'm all ears...Back to posts