A fullstack but simple mail server (smtp, imap, antispam, antivirus...).
50M+
We have migrated this repository to the Docker Mailserver Organization. This repository is therefore not maintained anymore. Please head over to the new repository for issues, pull requests and discussions. All work is now done there.
A fullstack but simple mail server (SMTP, IMAP, Antispam, Antivirus...). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade.
v7.2.0target/bin/v7.1.0[email protected] go to [email protected]Before opening an issue, please have a look this README, the Wiki and the Postfix/Dovecot documentation.
If you'd like to contribute, read CONTRIBUTING.md thoroughly.
Recommended:
Minimum:
Note: You'll need to deactivate some services like ClamAV to be able to run on a host with 512MB of RAM. Even with 1G RAM you may run into problems without swap, see FAQ.
Download the docker-compose.yml, compose.env, mailserver.env and the setup.sh files:
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml
wget https://raw.githubusercontent.com/tomav/docker-mailserver/master/mailserver.env
wget -O .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/compose.env
chmod a+x ./setup.sh
.env and mailserver.env to your liking:
.env contains the configuration for docker-composemailserver.env contains the configuration for the mailserver containerVAR=VAL lines (see Documentation).OVERRIDE_HOSTNAME=$HOSTNAME.$DOMAINNAME).Note: Variables in .env are expanded in the docker-compose.yml file only and not in the container. The file mailserver.env serves this case where environment variables are used in the container.
Note: If you want to use a bare domain (host name equals domain name) see FAQ.
If you'd like to use SELinux, add -Z to the variable SELINUX_LABEL in .env. If you want the volume bind mount to be shared among other containers switch -Z to -z
# without SELinux
docker-compose up -d mail
./setup.sh email add <user@domain> [<password>]
./setup.sh alias add postmaster@<domain> <user@domain>
./setup.sh config dkim
# with SELinux
docker-compose up -d mail
./setup.sh -Z email add <user@domain> [<password>]
./setup.sh -Z alias add postmaster@<domain> <user@domain>
./setup.sh -Z config dkim
Now that the keys are generated, you can configure your DNS server by just pasting the content of config/opendkim/keys/domain.tld/mail.txt in your domain.tld.hosts zone.
If you'd like to change, patch or alter files or behavior of docker-mailserver, you can use a script. Just place it the config/ folder that is created on startup and call it user-patches.sh. The setup is done like this:
$ pwd
/where/docker-mailserver/resides/
$ ls -lhA
-rw-r--r-- USER GROUP SIZE DATE .env
-rw-r--r-- USER GROUP SIZE DATE docker-compose.yml
-rw-r--r-- USER GROUP SIZE DATE mailserver.env
# 1. Either create the config/ directory yourself
# or let docker-mailserver create it on initial
# startup
$ mkdir config
$ cd config
# 2. Create the user-patches.sh script and make it
# executable
$ touch user-patches.sh
$ chmod +x user-patches.sh
$ ls -lh
-rwxr-xr-x USER GROUP SIZE DATE user-patches.sh
# 3. Edit it
$ vi user-patches.sh
$ cat user-patches.sh
#! /bin/bash
# ! THIS IS AN EXAMPLE !
# If you modify any supervisord configuration, make sure
# to run "supervisorctl update" afterwards.
set -euo pipefail
echo 'user-patches.sh started'
if ! grep '192.168.0.1' /etc/hosts
then
echo -e '192.168.0.1 some.domain.com' >> /etc/hosts
fi
sed -i "s/smtpd_sender_restrictions = /smtpd_sender_restrictions = reject_unknown_reverse_client_hostname, /" /etc/postfix/main.cf
sed -i "s/smtpd_sender_restrictions = /smtpd_sender_restrictions = reject_unknown_client_hostname, /" /etc/postfix/main.cf
echo 'user-patches.sh finished successfully'
And you're done. the user patches script runs right before starting daemons. That means, all the other configuration is in place, so the script can make final adjustments.
We are currently providing support for Linux. Windows is not supported and is known to cause problems. Similarly, macOS is not officially supported - but you may get it to work there. In the end, Linux should be your preferred operating system for this image, especially when using this mailserver in production.
docker-mailserver supports multiple domains out of the box, so you can do this:
./setup.sh email add [email protected]
./setup.sh email add [email protected]
./setup.sh email add [email protected]
docker-mailserverdocker-compose down
docker pull tvial/docker-mailserver:<VERSION TAG>
docker-compose up -d mail
You're done! And don't forget to have a look at the remaining functions of the setup.sh script with ./setup.sh -h.
If you got any problems with SPF and/or forwarding mails, give SRS a try. You enable SRS by setting ENABLE_SRS=1. See the variable description for further information.
| Protocol | Opt-in Encryption ¹ | Enforced Encryption | Purpose |
|---|---|---|---|
| SMTP | 25 | N/A | Transfer² |
| ESMTP | 587 | 465³ | Submission |
| POP3 | 110 | 995 | Retrieval |
| IMAP4 | 143 | 993 | Retrieval |
STARTTLS. On ports 110, 143 and 587, docker-mailserver will reject a connection that cannot be secured. Port 25 is required to support insecure connections.See the wiki for further details and best practice advice, especially regarding security concerns.
This example provides you only with a basic example of what a minimal setup could look like. We strongly recommend that you go through the configuration file yourself and adjust everything to your needs.
version: '3.8'
services:
mail:
image: docker.io/tvial/docker-mailserver:latest
hostname: mail # ${HOSTNAME}
domainname: domain.com # ${DOMAINNAME}
container_name: mail # ${CONTAINER_NAME}
ports:
- "25:25"
- "143:143"
- "587:587"
- "993:993"
volumes:
- maildata:/var/mail
- mailstate:/var/mail-state
- maillogs:/var/log/mail
- ./config/:/tmp/docker-mailserver/
environment:
- ENABLE_SPAMASSASSIN=1
- SPAMASSASSIN_SPAM_TO_INBOX=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- ENABLE_SASLAUTHD=0
- ONE_DIR=1
- DMS_DEBUG=0
cap_add:
- NET_ADMIN
- SYS_PTRACE
restart: always
volumes:
maildata:
mailstate:
maillogs:
version: '3.8'
services:
mail:
image: docker.io/tvial/docker-mailserver:latest
hostname: mail # ${HOSTNAME}
domainname: domain.com # ${DOMAINNAME}
container_name: mail # ${CONTAINER_NAME}
ports:
- "25:25"
- "143:143"
- "587:587"
- "993:993"
volumes:
- maildata:/var/mail
- mailstate:/var/mail-state
- maillogs:/var/log/mail
- ./config/:/tmp/docker-mailserver/
environment:
- ENABLE_SPAMASSASSIN=1
- SPAMASSASSIN_SPAM_TO_INBOX=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- ONE_DIR=1
- DMS_DEBUG=0
- ENABLE_LDAP=1
- LDAP_SERVER_HOST=ldap # your ldap container/IP/ServerName
- LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain
- LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain
- LDAP_BIND_PW=admin
- LDAP_QUERY_FILTER_USER=(&(mail=%s)(mailEnabled=TRUE))
- LDAP_QUERY_FILTER_GROUP=(&(mailGroupMember=%s)(mailEnabled=TRUE))
- LDAP_QUERY_FILTER_ALIAS=(|(&(mailAlias=%s)(objectClass=PostfixBookMailForward))(&(mailAlias=%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE)))
- LDAP_QUERY_FILTER_DOMAIN=(|(&(mail=*@%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE))(&(mailGroupMember=*@%s)(objectClass=PostfixBookMailAccount)(mailEnabled=TRUE))(&(mailalias=*@%s)(objectClass=PostfixBookMailForward)))
- DOVECOT_PASS_FILTER=(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
- DOVECOT_USER_FILTER=(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
- ENABLE_SASLAUTHD=1
- SASLAUTHD_MECHANISMS=ldap
- SASLAUTHD_LDAP_SERVER=ldap
- SASLAUTHD_LDAP_BIND_DN=cn=admin,dc=localhost,dc=localdomain
- SASLAUTHD_LDAP_PASSWORD=admin
- SASLAUTHD_LDAP_SEARCH_BASE=ou=people,dc=localhost,dc=localdomain
- SASLAUTHD_LDAP_FILTER=(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%U))
- [email protected]
- POSTFIX_MESSAGE_SIZE_LIMIT=100000000
cap_add:
- NET_ADMIN
- SYS_PTRACE
restart: always
volumes:
maildata:
mailstate:
maillogs:
If an option doesn't work as documented here, check if you are running the latest image! Values in bold are the default values.
Note: Since docker-mailserver v7.1.0, comparisons for environment variables are executed differently. If you previously used VARIABLE='' as the empty value, please update to now use VARIABLE=.
/var/mail-state) to allow persistence using docker volumesIf you enable Fail2Ban, don't forget to add the following lines to your docker-compose.yml:
cap_add:
- NET_ADMIN
Otherwise, iptables won't be able to ban IPs.
Please read the SSL page in the wiki for more information.
Configures the handling of creating mails with forged sender addresses.
Enables the Sender Rewriting Scheme. SRS is needed if your mail server acts as forwarder. See postsrsd for further explanation.
Set different options for mynetworks option (can be overwrite in postfix-main.cf) WARNING: Adding the docker network's gateway to the list of trusted hosts, e.g. using the network or connected-networks option, can create an open relay, for instance if IPv6 is enabled on the host machine but not in Docker.
docker-compose might use others (e.g. 192.168.0.0/16) use PERMIT_DOCKER=connected-networks in this caseNote: you probably want to set POSTFIX_INET_PROTOCOLS=ipv4 to make it work fine with Docker.
In case your network interface differs from eth0, e.g. when you are using HostNetworking in Kubernetes, you can set this to whatever interface you want. This interface will then be used.
eth0Set how many days a virusmail will stay on the server before being deleted
This Option is activating the Usage of POSTFIX_DAGENT to specify a ltmp client different from default dovecot socket.
Enabled by ENABLE_POSTFIX_VIRTUAL_TRANSPORT. Specify the final delivery of postfix
lmtp:unix:private/dovecot-lmtp (use socket)lmtps:inet:<host>:<port> (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/)lmtp:<kopano-host>:2003 (use kopano as mailstore)Set the mailbox size limit for all users. If set to zero, the size will be unlimited (default).
See mailbox quota.
Set the message size limit for all users. If set to zero, the size will be unlimited (not recommended!)
hostname command to get the mail server's canonical hostnameThis option has been added in November 2019. Using other format than Maildir is considered as experimental in docker-mailserver and should only be used for testing purpose. For more details, please refer to Dovecot Documentation.
Note: More details in http://www.postfix.org/postconf.5.html#inet_protocols
Enables regular pflogsumm mail reports.
This is a new option. The old REPORT options are still supported for backwards compatibility. If this is not set and reports are enabled with the old options, logrotate will be used.
Recipient address for pflogsumm reports.
From address for pflogsumm reports.
Interval for logwatch report.
Recipient address for logwatch reports if they are enabled.
Enables a report being sent (created by pflogsumm) on a regular basis.
Change the sending address for mail report
Changes the interval in which logs are rotated and a report is being sent (deprecated).
Note: This variable used to control logrotate inside the container and sent the pflogsumm report when the logs were rotated. It is still supported for backwards compatibility, but the new option LOGROTATE_INTERVAL has been added that only rotates the logs.
Defines the interval in which the mail log is being rotated.
Note that only the log inside the container is affected.
The full log output is still available via docker logs mail (or your respective container name).
If you want to control logrotation for the docker generated logfile see: Docker Logging Drivers.
Also note that by default the logs are lost when the container is recycled. To keep the logs, mount a volume.
Finally the logrotate interval may affect the period for generated reports. That is the case when the reports are triggered by log rotation.
/!\ Spam delivery: when Spamassassin is enabled, messages marked as spam WILL NOT BE DELIVERED.
Use SPAMASSASSIN_SPAM_TO_INBOX=1 for receiving spam messages.
SA_SPAM_SUBJECT.Junk folder.Note: this setting needs SPAMASSASSIN_SPAM_TO_INBOX=1
Note: this spamassassin setting needs ENABLE_SPAMASSASSIN=1
Note: this spamassassin setting needs `ENABLE
Content type
Image
Digest
sha256:c0d8c767c…
Size
342.8 MB
Last updated
over 5 years ago
docker pull tvial/docker-mailserver