Backup mails – backup and restore

After setting up a Dovecot instance and having imapsync running, how could I do the main task, the backup?

I use tar with its incremental option (infos about can be found here and here). Also I compress the backup, if you have pigz on your computer, use it, it makes the backup a lot faster because it uses all cpu cores.

Create first backup

sudo su -
cd /var/lib/docker/volumes/dovecot-server_dovecot-server-home-volume/_data/testaccount
tar -cvzf /root/testaccount-mail-backup-20240817.tgz -g /root/testaccount-mail-backup-20240817.inc Maildir/

To use all cores while compression:
tar -cvf /root/testaccount-mail-backup-20240817.tgz -g /root/testaccount-mail-backup-20240817.inc --use-compress-program=pigz Maildir/

Create next incremtal backup

cp /root/testaccount-mail-backup-20240817.inc /root/testaccount-mail-backup-20240818.inc
tar -cvf /root/testaccount-mail-backup-20240818.tgz -g /root/testaccount-mail-backup-20240818.inc --use-compress-program=pigz Maildir/

Restore mails vom backups

cd /var/lib/docker/volumes/dovecot-server_dovecot-server-home-volume/_data/testaccount
tar -xvf /root/testaccount-mail-backup-full-20240817.tgz --use-compress-program=pigz Maildir/ -g /dev/null
tar -xvf /root/testaccount-mail-backup-full-20240818.tgz --use-compress-program=pigz Maildir/ -g /dev/null
ls -la
# (1003:1003 is the group and user-id of the testaccount, change to the values for your account)
chown -R 1003:1003 Maildir/

Backup mails – setup of a dovecot server

Over the years, I have received a lot of mails, not all of them were moved to trash. Time to think about a solution to backup them and have way to restore them, if ever needed.

After a little thinking, I decided to use the following technics:

  1. Setup a local imap server (Dovecot) in Docker
  2. Setup local users in the dovecot server to sync the mails into it.
  3. Backup the mails stored in Maildir format by Dovecot with incremental backups.
  4. Try to restore the backup into a testaccount, to validate, the this is working

Currently I will execute the backup and restore steps manually. If I think after some time, it is bulletprof, I will think about how to automate. Right now the focus is on setup the infrastructure and commands to make backups possible.

How to setup a local dovecot server with Docker

I will run the Dovecot instance on one of my computers, currently it is running on my notebook.

Dockerfile

I use Ubuntu 24.04 for the Dovecot instance. 

FROM ubuntu:24.04

RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y dovecot-imapd locales \
&& apt-get clean \
&& locale-gen de_DE.UTF-8 \
&& update-locale LANG=de_DE.UTF-8 LC_MESSAGES=POSIX
COPY ./files/dovecot.conf /etc/dovecot/dovecot.conf
COPY ./files/addDovecotUser.sh /addDovecotUser.sh

RUN chmod +x /addDovecotUser.sh

ENV LANG=de_DE.utf8

EXPOSE 143

ENTRYPOINT ["dovecot", "-F"]

addDovecotUser.sh

To setup a user in the Dovecot instance, I have written the following script, which should be placed in the folder files in the folder, where the Dockerfile is placed.

#!/bin/bash

adduser $1
usermod -aG users $1
usermod -aG dovecot $1

mkdir -p /home/$1/Maildir/cur
mkdir -p /home/$1/Maildir/new
mkdir -p /home/$1/Maildir/tmp

chown -R $1:$1 /home/$1

dovecot.conf

Because I run and access the Dovecot instance only locally, I did not setup a configuration with SSL.

listen = *
auth_mechanisms = plain login
#log_path = /var/log/dovecot.log
log_path = /dev/stdout
mail_location = maildir:~/Maildir
protocols = imap
service imap-login {
inet_listener imap {
port = 143
}
}
ssl = no
disable_plaintext_auth = no

userdb {
driver = passwd
}
passdb {
driver = pam
}
protocol imap {
imap_idle_notify_interval = 2 mins
imap_max_line_length = 64 k
imap_client_workarounds = tb-extra-mailbox-sep
}
mail_max_userip_connections = 20

Docker Compose

At the end I use Docker Compose to setup and run the Dovecot instance. I limit the ressources for the Dovecot, for me it was enough.

services:
dovecot-server:
image: dovecot-server:latest
restart: always
cpus: 0.50
mem_limit: 1024m
mem_reservation: 256m
volumes:
- dovecot-server-home-volume:/home
networks:
- dovecot-net
ports:
- "143:143"
networks:
dovecot-net:
volumes:
dovecot-server-home-volume:

With

docker compose up 

you can start the local dovecot instance (I use Portainer with stacks to setup the infrastructure).

Setup a mailaccount in Dovecot

To create a new mailaccount in your Dovecot instance, you can execute bash inside the container and use it to execute the shell script. First execute the bash:

docker exec -it dovecot-server-dovecot-server-1 bash

Then execute the shell script and give the account name as an argument. It will ask you some more infos, which are not needed (except the password) and can be left empty (just press return):

root@f41d9f10fa99:/# ./addDovecotUser.sh test
info: Adding user `test' ...
info: Selecting UID/GID from range 1000 to 59999 ...
info: Adding new group `test' (1004) ...
info: Adding new user `test' (1004) with group `test (1004)' ...
info: Creating home directory `/home/test' ...
info: Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for test
Enter the new value, or press ENTER for the default
Full Name []: testaccount
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]
info: Adding new user `test' to supplemental / extra groups `users' ...
info: Adding user `test' to group `users' ...
root@f41d9f10fa99:/#
Now you should have an imap account which could be used.
In Thunderbird I used the following configuration:
Server: localhost
Port: 143
Connection security: none
Auth method: password, unencrypted

Next step will be setup of imapsync, which will be used to sync the mails by imap protocol.

Setup Docker in Fedora 31

For setting up Docker on Fedora 31, I used the documentation found here: https://docs.docker.com/install/linux/docker-ce/fedora/ 

Following problems occured:

1. Url to Docker repo seems to be wrong

Documentation mention to add https://download.docker.com/linux/fedora/docker-ce.repo as repo. With this, errors occur and docker-ce could not be installed. I had to use the following url, with this I could install it: https://download.docker.com/linux/fedora/31/x86_64/stable

sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/31/x86_64/stable

2. Error while executing docker run

After installation I tried Docker with the default example:

sudo docker run hello-world

Instead of showing the expected output it showed me the following error message:

docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "process_linux.go:297: applying cgroup configuration for process caused \"open /sys/fs/cgroup/docker/cpuset.cpus.effective: no such file or directory\"": unknown.

After searching around I found on bug mention the same error: https://github.com/microsoft/vscode-docker/issues/1402

In there it was pointing to a solution: https://fedoraproject.org/wiki/Common_F31_bugs#Docker_package_no_longer_available_and_will_not_run_by_default_.28due_to_switch_to_cgroups_v2.29

sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"

Problem is, that with Fedora 31 Cgroups v2 was enabled while Docker still uses Cgroups v1.