In this article, we will explain how you can easily migrate your Mailcow instance to another server. In this example, the server operating system CentOS 7 is obsolete and is going to be replaced with RockyLinux 9.
Upgrading your existing Mailcow instance is important and minimises the risk of a failed migration. Upgrading Mailcow is easy. Ensure you have backups then perfrom the following actions:
First move into the Mailcow directory:
cd /opt/mailcow-dockerized/
Now run the update file:
./update.sh
Sometimes update.sh will update itself and will prompt you to run the script again. If this is the case for you then run the script again.
For this step you can also refer to the Mailcow official documentation here.
The easiest way to move your Mailcow data across to another machine is to use the built-in Mailcow helper script to backup the required data then restore it on the target.
First stop docker:
systemctl stop docker.service
Create a directory to store the generated backup:
mkdir /opt/mailcow-dockerized/helper-scripts/mc-backup
Change directory to helper-scripts:
cd /opt/mailcow-dockerized/helper-scripts/
Now trigger the backup to start with the following:
./backup_and_restore.sh backup all
When prompted by the backup script the Mailcow backup directory should be set to the following:
/opt/mailcow-dockerized/helper-scripts/mc-backup/
Now change into the mc-backup directory:
cd /opt/mailcow-dockerized/helper-scripts/mc-backup/
TAR the directory with the following command:
tar czf mc_backup.tar.gz mailcow-2024-08-31-02-21-51/
Replace mailcow-2024-08-31-02-21-51 with the name of your directory that was generated by the backup script.
Now move the mc_backup.tar.gz to root directory:
mv /opt/mailcow-dockerized/helper-scripts/mc-backup/mc_backup.tar.gz /root/
Because we are going to backup the full Mailcow directory in the next step it's best to remove the generated backup within /opt/mailcow-dockerized to prevent huge backup size. Note... we already have the compressed version of this backup inside of /root/ anyway.
rm -rf /opt/mailcow-dockerized/helper-scripts/mc-backup/mailcow-2024-08-31-02-21-51/
We are doing this as a precaution and should not need this. Remember it's always best to have multiple backups of the data.
Change to the /opt/ directory:
cd /opt/
TAR up the full mailcow-dockerized folder with:
tar czf mc_full_backup.tar.gz mailcow-dockerized/
Now move the generated file to /root/ with:
mv /opt/mc_full_backup.tar.gz /root/
Copy the current working mailcow.conf file to /root/, this will be restored on the new server:
cp -a /opt/mailcow-dockerized/mailcow.conf /root/mailcow.conf
You should now have the following files inside of /root/:
Download these locally using SCP, or if you have a replacement server ready with SSH working SCP them across to /root/ on the new server as well as downloading them locally.
YOU SHOULD NOW HAVE A LOCAL BACKUP OF YOUR MAILCOW SERVER.
In this example, the old Mailcow server that was running CentOS 7 was rebuilt using RockyLinux 9. The IP addresses and DNS remained the same.
Update ALL packages on the server. If kernel received updates be sure to reboot the machine.
yum update -y
First, ensure that we have no other docker packages installed and that firewalld is removed, we will be adding the docker repository to ensure we get the latest versions that may not be available via the built-in repositories:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
firewalld
To add the docker repository to the server first we need to ensure that yum-utils are installed. To do this run:
yum install yum-utils -y
Now install the repository with:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
To install docker and the other required packages run the following:
yum install nano wget mlocate git docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
With the docker packages installed, start docker with:
systemctl start docker.service
Enable docker on boot with:
systemctl enable docker.service
SELINUX can be used but can cause problems so we disable this on the live machine with:
setenforce 0
To make your SELINUX changes persistent on boot edit the SELINUX file with:
nano /etc/selinux/config
With the file open find the following line:
SELINUX=enforcing
Replace this with:
SELINUX=disabled
Save the file and exit nano.
Flush iptables (if installed):
iptables -F
Upload the backups that you previously generated to your new server inside of /root/ you can do this using Filezilla or WinSCP. Whatever your preferred transfer client is.
If you already SCP'd these to root you do not need to follow this step.
Your root directory should have the following files:
[root@mail ~]# ls
mc_full_backup.tar.gz mc_backup.tar.gz mailcow.conf
If you have a completely new Mailcow server and your IP addresses have changed then now is a good time to change your DNS.
As part of the next steps the generate_config.sh script will ask for your mail server hostname etc, to generate certificates the hostname needs to resolve in DNS.
In order to restore the backups we first need to install a default instance of Mailcow on the server. First change the directory to /opt/:
cd /opt/
Now clone the Mailcow git repository with:
git clone https://github.com/mailcow/mailcow-dockerized
Once cloned change into the mailcow-dockerized directory:
cd /opt/mailcow-dockerized/
Before generating a config we need to ensure that our UMASK is equal to 0022. To do this simply run:
umask
Generate a dummy mailcow.conf file with the generator script:
./generate_config.sh
Do not worry, this will be replaced with the backup.
Now pull the repository with compose:
docker compose pull
Bring the containers online with:
docker compose up -d
Mailcow default installation should now be running and accessible inside of the web browser. You can access this using your hostname used when generating config providing your DNS is correct.
The default login details are:
Username: Admin
Password: moohoo
Create the backup directory with:
mkdir /opt/mailcow-dockerized/helper-scripts/mc-backup
Move the mailcow generated backup with:
mv /root/mc_backup.tar.gz /opt/mailcow-dockerized/helper-scripts/mc-backup/
Change the directory to the backup directory:
cd /opt/mailcow-dockerized/helper-scripts/mc-backup/
Extract the TAR file with:
tar -xvf mc_backup.tar.gz
Before triggering the restore it is advisable to stop docker:
systemctl stop docker.service
Backup the existing mailcow.conf file:
mv /opt/mailcow-dockerized/mailcow.conf /opt/mailcow-dockerized/mailcow.conf.backup
Restore your old mailcow.conf file:
cp -a /root/mailcow.conf /opt/mailcow-dockerized/mailcow.conf
First change directory to helper-scripts:
cd /opt/mailcow-dockerized/helper-scripts/
Run the following to start the restore:
./backup_and_restore.sh restore
When prompted provide the following as the path where backups are stored:
/opt/mailcow-dockerized/helper-scripts/mc-backup/
When prompted select restore point 1:
When prompted select dataset 0 for restore as this is for everything:
Mailcow will now restore all of your data for you. Close to the end of the restore you will be asked if you want to perform an RSYNC. Select NO but take note of the command. On some larger installs, mailboxes may require this if they are corrupt.
With the backup restored you can start mailcow. Change into the mailcow-dockerized directory:
cd /opt/mailcow-dockerized/
Trigger a fresh pull:
docker compose pull
Now compose up:
docker compose up -d
You should now be able to access Mailcow using your old credentials and view all of the restored data.
Finally, once you are confident that your backup and restore was successful you can remove the old backups from the server to save on disk space.
To do this run:
rm -rf /opt/mailcow-dockerized/helper-scripts/mc-backup/
rm -rf /root/mc_full_backup.tar.gz
rm -rf /root/mailcow.conf
Here are some official articles you can read regarding the migration and Mailcow in general:
https://docs.mailcow.email/backup_restore/b_n_r-backup/#manual
https://docs.mailcow.email/maintenance/migration/#__tabbed_1_1
https://docs.mailcow.email/getstarted/install/#users-with-a-mtu-not-equal-to-1500-eg-openstack
https://docs.mailcow.email/getstarted/install/#install-mailcow
For more helpful articles please visit our Knowledge Base and make a search.