,

Mailu Docker Compose Setup – Build Self Hosted Mail Server

Mailu is powerful full featured mail server build as a Docker image set. It is open source and free software backed by plethora of developers on github. Some of it’s features are

  • Standard email server, IMAP and IMAP+, SMTP and Submission
  • Advanced email features, aliases, domain aliases, custom routing
  • Web access, multiple Webmails and administration interface
  • User features, aliases, auto-reply, auto-forward, fetched accounts
  • Admin features, global admins, announcements, per-domain delegation, quotas
  • Security, enforced TLS, Letsencrypt!, outgoing DKIM, anti-virus scanner
  • Antispam, auto-learn, greylisting, DMARC and SPF
  • Freedom, all FOSS components, no tracker included

In this tutorial, we will learn to setup and install Mailu on Debian 9 step by step to build self hosted mail server.

Requirements for Mailu

Official Mailu documentation suggests installing Mailu on Debian 8 & 9 though it claims to work on Ubuntu as well. However, in this demonstration, I will stick to Debian 9. Also, Debian OS is available with all VPS/cloud providers, therefore you should have any issue at all. Just in case if you couldn’t find Debian on your hosting then start to try on Ubuntu.

I will be using Turnkey Internet for the demonstration as they provide VPS with open port 25, necessary for emailing.

Initial DNS Setup

You need to create few records for domain to get started. They are as follows.

TypeHostValue
AmailYour IP address
MX@mail.yourdomain.com 10

Initial Server Setup for Mailu

After the above step, you need to connect to a remote server using IP address and password provided by the hosting. If you are on Windows, then you will need a special SSH client to connect to the remote server. Some of the SSH clients are Putty, BitVise, etc.

Once you are connected to remote server, you need to update the server

apt-get install sudo
sudo -i
apt-get update -y

Next, you have to set the hostname

hostnamectl set-hostname mail.yourdomain.com

Also, set fully qualified domain name (FQDN). For that edit /etc/hosts file

apt install nano -y
nano /etc/hosts

Now, add the line to this file as follows. Don’t forget to replace 123.15.116.167 with your server IP. Just in case if there’s line starting with your IP address is already present make sure following text is present as well or edit it.

123.15.116.167 mail.yourdomain.com mail

Next add firewall rules

sudo ufw allow 25,80,443,110,143,465,587,993,995/tcp

After these steps, your server is ready to install Mailu.

Install Docker and Docker-Compose

First of all you need to install Docker & Docker-Compose to begin with Mailu.

Install Docker on Debian

Start with allowing apt to use repository over HTTPS:

 sudo apt-get update
 sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

Next, add Docker’s official GPG key:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Now, you need to set up stable repository with following command.

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

After that, you can install docker with following commands

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Verify that Docker Engine is installed correctly by running the hello-world image.

 sudo docker run hello-world

Install Docker-Compose

Now, docker engine has been installed successfully, it’s time to install docker-compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   633  100   633    0     0   4914      0 --:--:-- --:--:-- --:--:--  4906
100 12.1M  100 12.1M    0     0  40.7M      0 --:--:-- --:--:-- --:--:-- 40.7M

Update permissions for binary

sudo chmod +x /usr/local/bin/docker-compose

Install Mailu

Now, docker and docker-compose installed, it’s time to install Mailu.

Mailu has made it super easy to generate bin file that you will need to install mail server. Simply go to following link and fill the details as follows.

  • https://setup.mailu.io/

On following screen select compose

On next screen, fill in the blanks circled in red to generate the configuration file

After that, you will be given with set of commands to run, which will install Mailu mailserver.

Now, let’s execute commands from above screenshot, but with some additional steps.

First command is to make directory.

root@mail:~# mkdir /mailu

Now, download the configuration files you generated

root@mail:~# cd /mailu
root@mail:/mailu# wget http://setup.mailu.io/1.7/file/f9c808a6-ec48-4499-b4da-346deb0480f3/docker-compose.yml
root@mail:/mailu# wget http://setup.mailu.io/1.7/file/f9c808a6-ec48-4499-b4da-346deb0480f3/mailu.env

Then, review the configuration files. First open docker.yml file

root@mail:/mailu# nano docker-compose.yml

You don’t have to make any changes in this file.

# This file is auto-generated by the Mailu configuration wizard.
# Please read the documentation before attempting any change.
# Generated for compose flavor

version: '2.2'

services:

  # External dependencies
  redis:
    image: redis:alpine
    restart: always
    volumes:
      - "/mailu/redis:/data"

  # Core services
  front:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    logging:
      driver: json-file
    ports:
      - "159.203.66.253:80:80"
      - "::1:80:80"
      - "159.203.66.253:443:443"
      - "::1:443:443"
      - "159.203.66.253:25:25"
      - "::1:25:25"
      - "159.203.66.253:465:465"
      - "::1:465:465"
      - "159.203.66.253:587:587"
      - "::1:587:587"
      - "159.203.66.253:110:110"
      - "::1:110:110"
      - "159.203.66.253:995:995"
      - "::1:995:995"
      - "159.203.66.253:143:143"
      - "::1:143:143"
      - "159.203.66.253:993:993"
      - "::1:993:993"
    volumes:
      - "/mailu/certs:/certs"
      - "/mailu/overrides/nginx:/overrides"

  resolver:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}unbound:${MAILU_VERSION:-1.7}
    env_file: mailu.env
    restart: always
    networks:
      default:
        ipv4_address: 192.168.203.254

  admin:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/data:/data"
      - "/mailu/dkim:/dkim"
    depends_on:
      - redis

  imap:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/mail:/mail"
      - "/mailu/overrides:/overrides"
    depends_on:
      - front

  smtp:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}postfix:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/overrides:/overrides"
    depends_on:
      - front
      - resolver
    dns:
      - 192.168.203.254

  antispam:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}rspamd:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/filter:/var/lib/rspamd"
      - "/mailu/dkim:/dkim"
      - "/mailu/overrides/rspamd:/etc/rspamd/override.d"
    depends_on:
      - front
      - resolver
    dns:
      - 192.168.203.254

  # Optional services
  antivirus:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}clamav:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/filter:/data"
    depends_on:
      - resolver
    dns:
      - 192.168.203.254

  webdav:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/dav:/data"

  fetchmail:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}fetchmail:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    depends_on:
      - resolver
    dns:
      - 192.168.203.254

  # Webmail
  webmail:
    image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}roundcube:${MAILU_VERSION:-1.7}
    restart: always
    env_file: mailu.env
    volumes:
      - "/mailu/webmail:/data"
    depends_on:
      - imap


networks:
  default:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.203.0/24

Next open mailu.env

root@mail:/mailu# nano mailu.env

Here change the SECRET_KEY. You can generate secret key on command line itself. Also, you can do few other changes as well as per your need.

# Mailu main configuration file
#
# This file is autogenerated by the configuration management wizard for compose flavor.
# For a detailed list of configuration variables, see the documentation at
# https://mailu.io

###################################
# Common configuration variables
###################################

# Set to a randomly generated 16 bytes string
SECRET_KEY=zahdieghae6Ceice

# Subnet of the docker network. This should not conflict with any networks to which your system is connected. (Internal and external!)
SUBNET=192.168.203.0/24

# Main mail domain
DOMAIN=swdlv.com

# Hostnames for this server, separated with comas
HOSTNAMES=mail.swdlv.com

# Postmaster local part (will append the main mail domain)
POSTMASTER=admin

# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt)
TLS_FLAVOR=letsencrypt

# Authentication rate limit (per source IP address)
AUTH_RATELIMIT=10/minute;1000/hour

# Opt-out of statistics, replace with "True" to opt out
DISABLE_STATISTICS=True

###################################
# Optional features
###################################
# Expose the admin interface (value: true, false)
ADMIN=true

# Choose which webmail to run if any (values: roundcube, rainloop, none)
WEBMAIL=roundcube

# Dav server implementation (value: radicale, none)
WEBDAV=radicale

# Antivirus solution (value: clamav, none)
ANTIVIRUS=clamav

###################################
# Mail settings
###################################

# Message size limit in bytes
# Default: accept messages up to 50MB
# Max attachment size will be 33% smaller
MESSAGE_SIZE_LIMIT=50000000

# Networks granted relay permissions
# Use this with care, all hosts in this networks will be able to send mail without authentication!
RELAYNETS=

# Will relay all outgoing mails if configured
RELAYHOST=

# Fetchmail delay
FETCHMAIL_DELAY=600

# Recipient delimiter, character used to delimiter localpart from custom address part
RECIPIENT_DELIMITER=+

# DMARC rua and ruf email
DMARC_RUA=admin
DMARC_RUF=admin

# Welcome email, enable and set a topic and body if you wish to send welcome
# emails to all users.
WELCOME=false
WELCOME_SUBJECT=Welcome to your new email account
WELCOME_BODY=Welcome to your new email account, if you can read this, then it is configured properly!

# Maildir Compression
# choose compression-method, default: none (value: bz2, gz)
COMPRESSION=
# change compression-level, default: 6 (value: 1-9)
COMPRESSION_LEVEL=

###################################
# Web settings
###################################

# Path to redirect / to
WEBROOT_REDIRECT=/webmail

# Path to the admin interface if enabled
WEB_ADMIN=/admin

# Path to the webmail if enabled
WEB_WEBMAIL=/webmail

# Website name
SITENAME=Mailu

# Linked Website URL
WEBSITE=https://mailu.io

###################################
# Advanced settings
###################################

# Log driver for front service. Possible values:
# json-file (default)
# journald (On systemd platforms, useful for Fail2Ban integration)
# syslog (Non systemd platforms, Fail2Ban integration. Disables `docker-compose log` for front!)
# LOG_DRIVER=json-file

# Docker-compose project name, this will prepended to containers names.
COMPOSE_PROJECT_NAME=mailu

# Default password scheme used for newly created accounts and changed passwords
# (value: BLF-CRYPT, SHA512-CRYPT, SHA256-CRYPT, MD5-CRYPT, CRYPT)
PASSWORD_SCHEME=BLF-CRYPT

# Header to take the real ip from
REAL_IP_HEADER=

# IPs for nginx set_real_ip_from (CIDR list separated by commas)
REAL_IP_FROM=

# choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no)
REJECT_UNLISTED_RECIPIENT=

# Log level threshold in start.py (value: CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET)
LOG_LEVEL=WARNING

###################################
# Database settings
###################################
DB_FLAVOR=sqlite
root@mail:/mailu# apt install pwgen

root@mail:/mailu# pwgen 16

mair3aer7jaiQu0b ohs5de6se5shueN6 ex6ahxeghiVie3ye eiqu8oot7eiYo3Th
oofaePh2taireeL3 Po5oS9shagi6pe0f ohNgaeChooShie0e ipei5Einaecae2zu
Keingoh4ithai3lo OhthohJ4quoofaew oiY6aegh9ohthei9 Aepa7meeleeceire
iacuos6eshaaSimi doh1ohtheiHooph3 ixooZ0ohb4eeHi6w Xak2Doo9eifi2nea
an5iQu9ielae6Goo zahdieghae6Ceice cahrai1nooj2UY1P ohDooC4lith4uu4d

Finally, compose the project with following command

root@mail:/mailu# export MAILU_VERSION=1.8
root@mail:/mailu# docker-compose -p mailu up -d

At last, you need to create admin account.

root@mail:/mailu# docker-compose -p mailu exec admin flask mailu admin admin inlearn.in PASSWORD

Mailu First Run

Now go to the browser and open https://yourdomain.com/admin

Login with username [email protected] and PASSWORD

mailu-admin-login

On next, screen change the admin password. Further, you can explore yourself.

Final DNS Setup

To wrap up Mailu Docker installation, you need to create 3 TXT DNS records.

Generate DKIM & DMARC Keys

To generate DKIM & DMARC keys go to Mail Domains and then Details of domain as shown below.

dkim-mailu-domain

Then on next screen click on Generate Keys

generate-dkim-mailu-smtp-server

This will generate DKIM Keys and DMARC both.

dkim-dmarc-spf-key

Now, you have all 3 records viz, DKIM, DMARC and SPF. Go to your domain registrar and make these entries.

Conlcusion

Mailu Docker Setup is easy compared to other mailing software. Also, it give you lots of insight regarding your mail server which will prove beneficial when you start using it. You can also add additional domain easily.

6 replies
  1. Eros
    Eros says:

    Please another question between Mailcow and Mailu who is the best ?

    What do you think about cloudron mail server,mailinabox,iredmail,openemail.io comparing to mailcow and mailu?

    Do you think security mail gateway such as Proxmox Mail Gateway is require or all these mail server security are enough?

    Reply
  2. mohamed
    mohamed says:

    Dear ,

    Appreciate your guide
    FYI Docker Overrides the host network configuration
    so enabling the Fire wall is useless , unless you managed the network of you Docker containers

    Reply
  3. Sezer Ozdemir
    Sezer Ozdemir says:

    I’m getting ERROR: for front Cannot start service front: driver failed programming external connectivity on endpoint mailu_front_1 …. bind: cannot assign requested address

    How can I solve this problem ?

    Reply
  4. dacan
    dacan says:

    i used debian 9.4, and i noticed that my server is not updating “apt-get update -y”, do u have a solution to this?

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *