Mail Server Deployment Using Docker
Mail Server Deployment Using Docker
For this example we will assume the domain mydomain.online. Change accordingly. we also
assume that the docker compose and certificates renewal script are located
in /home/ubuntu/docker-mailserver/.
Documentation
https://docker-mailserver.github.io/docker-mailserver/latest/
Steps
1. Register a domain
2. Secure a fixed IP address
3. Create an 'A' DNS record in your domain for your server
4. Configure Reverse DNS for this IP address
5. Generate mail certificates
6. Register SPF record for the server on DNS
7. Publish DMARC Policy
8. Deploy the server
9. Open in and outboud ports
1. Register a domain
In aws you need an "Elastic IP address". Other providers also have this product.
You must create a type 'A' record for your email server. for instance:
The reverse DNS of the IP must match the DNS of the server. For instance, executing nslookup
108.128.117.83 should return the FDQN of the mail server: 83.117.128.108.in-
addr.arpa name = mail.mydomain.online. For aws check "Use reverse DNS for email
applications" in https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-
eip.html
5. Generate mail certificates
https://eff-certbot.readthedocs.io/en/latest/install.html#running-with-docker
https://docker-mailserver.github.io/docker-mailserver/latest/config/security/ssl/#lets-encrypt-
recommended Before even starting the mail server you must get certificates. You can do that by
running the letsencrypt certbot and answer some questions, like the full DNS name of the mail
server. In our case: mail.mydomain.online
10 3 * * 0 /home/ubuntu/docker-mailserver/renewcerts.sh >>
/home/ubuntu/docker-mailserver/renewcerts.log 2>&1
The renewcerts.sh file:
#!/bin/bash
This indicates that the only server trusted to send mail from mydomain.online is the
server mail.mydomain.online and no other.
version: "3.8"
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:13.3.1
container_name: mailserver
restart: always
# Provide the FQDN of your mail server here (Your DNS MX record
should point to this value)
hostname: mail.mydomain.online
ports:
- "25:25"
- "465:465"
- "587:587"
- "993:993"
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/
# https://docker-mailserver.github.io/docker-
mailserver/latest/config/security/ssl/#lets-encrypt-recommended
- /etc/letsencrypt:/etc/letsencrypt
- /etc/localtime:/etc/localtime:ro
environment:
# https://docker-mailserver.github.io/docker-
mailserver/latest/config/environment/
- LOG_LEVEL=info # info
- ENABLE_RSPAMD=0
- ENABLE_FAIL2BAN=0
- ENABLE_POSTGREY=0
- ENABLE_CLAMAV=0
- ENABLE_SPAMASSASSIN=0
- ENABLE_IMAP=1
- POSTFIX_MAILBOX_SIZE_LIMIT=1
- TZ=Europe/Lisbon
# Using letsencrypt for SSL/TLS certificates. Enable only after
creating first request. Fails if there are no certificates
- SSL_TYPE=letsencrypt
- TLS_LEVEL=modern
# Allow sending emails from other docker containers:
# Beware creating an Open Relay: https://docker-
mailserver.github.io/docker-
mailserver/latest/config/environment/#permit_docker
# - PERMIT_DOCKER=network
# You may want to enable this: https://docker-
mailserver.github.io/docker-
mailserver/latest/config/environment/#spoof_protection
# See step 6 below, which demonstrates setup with
enabled/disabled SPOOF_PROTECTION:
- SPOOF_PROTECTION=1
# cap_add:
# - NET_ADMIN # For Fail2Ban to work
Before the mail server fully starts you must create at least one mailbox.
docker compose up -d
docker exec -it mailserver /bin/bash
setup email add [email protected] mySuperSecretPass-01!
exit
docker compose down
docker compose up -d
https://docker-mailserver.github.io/docker-mailserver/latest/config/user-management/
https://docker-mailserver.github.io/docker-mailserver/edge/config/best-
practices/dkim_dmarc_spf/
https://docker-mailserver.github.io/docker-mailserver/edge/config/best-
practices/dkim_dmarc_spf/
Setting up DKIM (DomainKeys Identified Mail) for your Docker Mailserver is an essential step to
improve email deliverability and help prevent email spoofing. DKIM adds a digital signature to
the emails sent from your domain, which receiving mail servers can use to verify that the email
was indeed sent from an authorized mail server for your domain.
Here's a general outline on how to generate DKIM keys for your Docker Mailserver:
First you must have te container up and running. Using the previous docker-compose.yaml file
you must execute (and wait for it to be ready):
docker compose up -d
Then you go inside the container to generate DKIM keys by running the setup.sh script with
the config dkim option. You'll also need to specify the domain for which you're generating the
DKIM keys. Here's how you can do it:
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp4BrmmqBmibHi2FGEXe2Eixgw9GX2le
TyLcAIN9Z3z83+kPj+E6gRBUaMDew24qpBXUdb4nKCV1iO6zXHMomDQkAbbcXT5o3jRGMlc6syX
Cae86Arz82prfC63uIJVn6N/6MbOn3ytP/QkhzAXRUA4J8hpin269EuzhUuFMaIRxrde1xssepT3yEuT/
cV8bHQUzrnF7182jz+"
Becomes:
"TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFwNEJybW1xQm1pYk
hpMkZHRVhlMkVpeGd3OUdYMmxlVHlMY0FJTjlaM3o4MytrUGorRTZnUkJVYU1EZXcyNHFwQkdY
VWRiNG5LQ1YxaU82elhITW9tRFFrQWJiY1hUN8zalJHTWxjNnN5WENhZTg2QXJ6ODJwcmZDNjN1
SUpWbjZOLzZNYk9uM3l0UC9Ra2h6QVhSVUE0SjhocGluMjY5RXV6aFV1Rk1hSVJ4cmRlMXhzc2Vw
VDN5RXVUL2NWOGJIUVV6cm5GNzE4Mmp6Kw=="
Now you just create a TXT record named "mail._domainkey" with the following content (don't
break lines, should be a single line):
v=DKIM1; h=sha256; k=rsa;
p=TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFwN
EJybW1xQm1pYkhpMkZHRVhlMkVpeGd3OUdYMmxlVHlMY0FJTjlaM3o4MytrUGor
RTZnUkJVYU1EZXcyNHFwQkdYVWRiNG5LQ1YxaU82elhITW9tRFFrQWJiY1hUNW8
zalJHTWxjNnN5WENhZTg2QXJ6ODJwcmZDNjN1SUpWbjZOLzZNYk9uM3l0UC9Ra2
h6QVhSVUE0SjhocGluMjY5RXV6aFV1Rk1hSVJ4cmRlMXhzc2VwVDN5RXVUL2NWO
GJIUVV6cm5GNzE4Mmp6Kw==
Important note:
If running on aws you must open a support ticket to open ports 25 and 587 outbound. Even if
you specify these in the outbound rules, aws will block them:
https://repost.aws/knowledge-center/ec2-port-25-throttle
User management
Creating a new Account
https://docker-mailserver.github.io/docker-mailserver/latest/config/user-management/