Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

Set up your own mail server with Mailcow

profile picture
Author
kev-ac
Published
2023-02-01
Time to read
9 minutes reading time

(The original tutorial was written by ntimo in 2019 and was updated to the current state and new topics)

Introduction

In this tutorial you will setup your own mail server running on an Ubuntu Server in the Hetzner Cloud. With Mailcow you can host your own mail server with your custom domain. Mailcow also provides a way to sync your Contacts and Calendar.

Official documentation: https://docs.mailcow.email/
Project Website: https://mailcow.email
GitHub: https://github.com/mailcow/mailcow-dockerized
Community forum: https://community.mailcow.email

Prerequisites

  • You need a domain name
  • A bit of knowledge of how Docker works
  • Hetzner Cloud servers by default block port 25 and 465 to protect from spammers. You can request to get the ports unblocked after your first invoice was paid. This basically acts as a simple verification, that you are not a spammer.

Step 1 - Create a new Cloud server

  • Sign-in to the Cloud Console
  • Create a new project and name it whatever you want
  • Choose a server location and type depending on your needs. See below for tips if you are unsure.
  • Click Add Server and select your server image. This tutorial is based around Ubuntu 22.04 but can easily be adapted to Debian 11, which is more stable and lighter.
  • Choose the resources you need from Type
  • Click on the field Cloud config enter this: #include https://get.docker.com (this will install docker)
  • Select your SSH key
    • You can read this article to learn how to generate an SSH key
  • Write your server hostname in name input (mail.example.com)
  • Click Create & Buy Now

How to choose the correct server location and type

Choose a server location which is geographically closest to you or your user base.

In regard to the correct server type, keep in mind that Mailcow requires at least 7GB RAM to function properly.
Mailcow is a fully-featured groupware solution. Having that said, the lowest server type available would be a CX31* or CPX31.

*Availability of the CX line depends on your chosen location. As of the time of writing CX servers are not available in US locations.

Step 2 - Setup DNS

Basically, you want to create a new DNS record called mail.example.com and add your server IPv4 (A record) and IPv6 (AAAA record) to it. Then, you can set up your domains MX record to point to your mail.example.com subdomain that you just created. You also need to set up an autodiscover.example.com and autoconfig.example.com subdomain. Both should be of the type CNAME and point to mail.example.com.

Your DNS configuration should look similar to this:

# Name              Type       Value
mail                IN A       10.0.0.1
mail                IN AAAA    2001:db8:1234::1
autodiscover        IN CNAME   mail
autoconfig          IN CNAME   mail

@                   IN MX 10   mail

For a more advanced setup, there are more DNS records you should watch out for in the Mailcow documentation.

Step 3 - Install updates and Docker Compose on the server

Wait a few seconds for the server to startup and then connect to it using SSH and your private key. Now you should install available updates on your server by running:

apt update && apt upgrade -y

This is a good time to reboot the server after all upgrades are finished, especially if there are kernel updates.

Step 4 - Clone the Mailcow Repository

Now we are going to clone the Mailcow GitHub repository, so first you need to cd to /opt with:

cd /opt

Once you are in /opt, you can run:

git clone https://github.com/mailcow/mailcow-dockerized

Step 5 - Create the config, pull the Docker containers, and start Mailcow

When you run ./generate_config.sh, you need the latest version of docker compose v2. You can use docker compose version to get your version and check if you need to upgrade to version 2.

To create the config, change your working directory to /opt/mailcow-dockerized with cd /opt/mailcow-dockerized and run ./generate_config.sh this will generate the config. Now you have to enter your domain name (something like mail.example.com).

We are nearly done. Now, you have to run docker compose pull to pull the docker images.

In order to start Mailcow, run docker compose up -d

Step 6 - Set up the reverse DNS entries

To set up your reverse DNS entries, do the following steps:

  • Go to the Hetzner Cloud console and click on your project
  • Select the server you just created and go to the NETWORKING tab
  • Click the three dots near your IPv4 address, select Edit Reverse DNS, enter your domain (mail.example.com), and confirm the change.
  • Click the three dots near your IPv6 subnet, select Edit Reverse DNS, and type ::1 into the field where the IP is below your domain name (mail.example.com).

Step 7 - First login to your Mailcow instance

Visit your Mailcow instance at https://mail.example.org and log in with the default credentials:

  • Username: admin
  • Password: moohoo

Important: Change your password as soon as possible, as leaving it as is opens your server up for breaches.

Step 8 - Add domain(s) to Mailcow

Now, you can add your domain to Mailcow. Simply go to Configuration -> Mail setup. Add your domain under the tab "Domain".

Step 9 - Setup DKIM

Now, when you go back to Configuration -> Configuration & Details you can set up DKIM. In the Configuration tap, select DKIM in the sidebar. It should be at the top. Scroll down till you see the mask where you can enter your domain. Simply click Select domains with missing keys shortcut to have your domain name filled in. Now, select a 2048 key and click on Add. Once the key is added, you can copy the public key and create a DNS TXT entry called dkim._domainkey with the content you just copied.

Step 10 - Create a mailbox

When you go back to Configuration -> Mail setup, you can create a mailbox and log into SOGo by accessing it at https://mail.example.com/SOGo.

Step 11 - Creating backups

Backups are essential for most server setups. Your mail server is no different. Mailcow provides a very simple way to create backups of your mail data.

Create a manual backup

  • Connect to your server using your SSH key.
  • Go to the Mailcow directory which contains the backup script /opt/mailcow-dockerized/helper-scripts
  • Run the backup script ./backup_and_restore.sh backup all --delete-days 7
    • The script will ask you for your backup location.
    • --delete-days 7 will remove any backup in the chosen directory which is older than 7 days. Alter the value or remove it entirely depending on your needs.

The process can take some minutes to a few hours depending on your mails size and server type.

Create automated backups

  • Connect to your server using your SSH key.
  • Run crontab -e to enter your cron task list.
    • If it is the first time you run this command, you will be asked to choose an editor. Choose (1) /bin/nano as it is the easiest for new users.
  • Paste the following into your crontab and update the details depending on your setup (see below):
0 5 * * * MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all --delete-days 7

MAILCOW_BACKUP_LOCATION is the folder the backups will be written to. If you have a big mail database, consider adding a Volume to your server to expand its storage.
--delete-days 7 will remove any backup in the chosen directory which is older than 7 days. Alter the value or remove it entirely depending on your needs.

General recommendations

Consider the general rules of storing backups when creating a Mailcow instance. This includes having a copy of your backup in another location than your servers' disk (for example a Hetzner Storagebox).

Step 12 - Updating your Mailcow instance

Updates for Mailcow are generally released once per month by the authors. If there are urgent security patches or bugs, more updates are released. It is wise to keep an eye on the releases page of Mailcow for information about changes.

Before executing updates, it is recommended to check if you have current backups of your data. In the Hetzner Cloud Console, you can also create a Snapshot of your server to quickly revert back to a working state if something goes wrong.
If you don't want to use Hetzner Snapshots, Mailcow also has a built-in way to roll back from updates.

  • Connect to your server using your SSH key.
  • Go to the Mailcow directory /opt/mailcow-dockerized
  • Run ./update.sh
    • The script will first check if there is a new update.sh file available and will update it. If this is the case, you have to re-run the script.
    • Then, all other updates will be pulled and prepared to be updated. You have to confirm the update.
  • At the end, Mailcow will ask if you want to delete the now unused components. Select no and optionally delete them manually later on to be prepared if something went wrong.
  • After the update is done, Mailcow will start up all services and run internal upgrades. Do not shut down your server or the docker containers to prevent data corruption.
License: MIT
Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue
Try Hetzner Cloud

Get 20€ free credit!

Valid until: 31 December 2024 Valid for: 3 months and only for new customers
Get started
Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more