Introduction #
Setting up a secure and easy-to-administer mail server can be challenging. Docker-Mailserver simplifies this process by providing a production-ready, full-stack containerized mail server (SMTP, IMAP, Anti-spam, Anti-virus, etc.). Using only configuration files, it keeps everything simple and versioned, eliminating the need for SQL databases.
With Docker-Mailserver and this article, you can set up your mail server within an hour, even if you have no prior knowledge.
Prerequisites #
- Docker running on a Linux Server
- A domain name with the ability to change DNS entries
Project structure #
We’ll use the same project structure as in my article about Traefik + Authelia:
mkdir -p $HOME/docker-projects/docker-mailserver
cd $HOME/docker-projects/docker-mailserver
Set up Docker-Mailserver #
Create docker-compose.yml #
Download the docker-compose.yml
file for docker-mailserver:
curl -o docker-compose.yml https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/compose.yaml
Modify the docker-compose.yml
file. Adjust hostname
according to your FQDN:
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mailserver
# Provide the FQDN of your mail server here (Your DNS MX record should point to this value)
hostname: mail.example.com
env_file: mailserver.env
# More information about the mail-server ports:
# https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/
ports:
- "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead)
- "143:143" # IMAP4 (explicit TLS => STARTTLS)
- "465:465" # ESMTP (implicit TLS)
- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
volumes:
- ./docker-data/dms/mail-data/:/var/mail/
- ./docker-data/dms/mail-state/:/var/mail-state/
- ./docker-data/dms/mail-logs/:/var/log/mail/
- ./docker-data/dms/config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
restart: always
stop_grace_period: 1m
# Uncomment if using `ENABLE_FAIL2BAN=1`:
# cap_add:
# - NET_ADMIN
healthcheck:
test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
timeout: 3s
retries: 0
Create mailserver.env #
Download the mailserver.env
:
curl -o mailserver.env https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/mailserver.env
Review and adjust the file as needed. For example, to set your timezone:
TZ=Europe/Berlin
Activate Spam Protection #
In mailserver.env
, configure spam protection:
ENABLE_OPENDKIM=0
ENABLE_OPENDMARC=0
ENABLE_POLICYD_SPF=0
ENABLE_CLAMAV=1
ENABLE_RSPAMD=1
RSPAMD_LEARN=1
Set Up SSL Certificates #
If you’re using Traefik, add this section to your docker-compose.yml
:
services:
mailserver:
#...
whoami:
image: docker.io/traefik/whoami:latest
networks:
- docknet
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.mail.rule=Host(`mail.example.com`)'
- 'traefik.http.routers.mail.entrypoints=https'
- 'traefik.http.routers.mail.tls=true'
- 'traefik.http.routers.mail.tls.certresolver=letsencrypt'
- 'traefik.http.routers.mail.middlewares=authelia@docker'
- 'traefik.http.routers.mail.service=mail-service'
- 'traefik.http.services.mail-service.loadbalancer.server.port=80'
expose:
- 80
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
docknet:
name: docknet
external: true
Start the Server #
Now, start your Docker-Mailserver:
docker compose up -d
Create Mail Addresses #
Create the postmaster address:
docker exec -it mailserver setup email add postmaster@example.com very-secret-password
Create additional email addresses:
docker exec -it mailserver setup email add your.name@example.com another-s3c3t-password
Create alias addresses. All emails sent to hello@example.com will be then forwarded to your.name@example.com:
docker exec -it mailserver setup alias add hello@example.com your.name@example.com
DNS Setup #
Basic #
In my article Single-Sign-On using Traefik 3, Authelia 4 and Let’s Encrypt SSL, I already created some wildcard DNS records for my domain name.
In addition, we need a MX record which indicates the Fully Qualified Domain Name (FQDN) under which the mail server for a domain or subdomain can be reached. Let’s add a MX DNS record:
Type | Name | Content |
---|---|---|
MX |
@ |
mail.example.com |
Advanced #
DKIM #
Run this command to generate DKIM keys:
docker exec -it mailserver setup config dkim
Then add a DNS TXT record:
Type | Name | Content |
---|---|---|
TXT |
mail._domainkey |
v=DKIM1; k=rsa; p=MIIxxx |
DMARC #
We don’t need to generate DMARC keys, but we have to add a TXT entry for DMARC:
Type | Name | Content |
---|---|---|
TXT |
_dmarc.example.com. |
v=DMARC1; p=none; sp=none; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400; rua=mailto:postmaster@example.com; ruf=mailto:postmaster@example.com |
SPF #
Add also a TXT entry for TXT:
Type | Name | Content |
---|---|---|
TXT |
example.com. |
v=spf1 mx ~all |
Conclusion #
You now have a fully functional mail server running with Docker-Mailserver. This guide covered the basic setup, but Docker-Mailserver offers extensive customization options to fit your specific needs. Feel free to explore further and adapt the setup to your requirements.
Thank you #
I appreciate your feedback on this tutorial. If you have suggestions, improvements, or encounter any bugs, please don’t hesitate to reach out. I’ll strive to keep this guide updated with the latest best practices and features.