Go to file
Brennan Kinney 3b4f44e837
tests(fix): Adjust for local testing conditions (#2606)
* tests(fix): Increase some timeouts

Running tests locally via a VM these tests would fail sometimes due to the time from being queued and Amavis actually processing being roughly around 30 seconds.

There should be no harm in raising this to 60 seconds, other than delaying a failure case which will ripple through other time sensitive tests.

It's better to pass when functionality is actually correct but just needs a bit longer to complete.



* tests(fix): Don't setup an invalid hostname

During container startup `helpers/dns.sh` would panic with `hostname -f` failing.

Dropping `--domainname` for this container is fine and does not affect the point of it's test.

---

It's unclear why this does not occur in CI. Possibly changes within the docker daemon since as CI runs docker on Ubuntu 20.04? (2020).

For clarity, this may be equivalent to setting a hostname of `domain.com.domain.com`, or `--hostname` value truncated the NIS domain (`--domainname`) of the same value.

IIRC, it would still fail with both options using different values if `--hostname` was multi-label. I believe I've documented how non-deterministic these options can be across different environments.

`--hostname` should be preferred. There doesn't seem to be any reason to actually need `--domainname` (which is NIS domain name, unrelated to the DNS domain name). We still need to properly investigate reworking our ENV support that `dns.sh` manages.

---

Containers were also not removing themselves after failures either (missing teardown). Which would cause problems when running tests again.



* chore: Normalize white-space

Sets a consistent indent size of 2 spaces. Previously this varied a fair bit, sometimes with tabs or mixed tabs and spaces.

Some formatting with blank lines.

Easier to review with white-space in diff ignored. Some minor edits besides blank lines, but no change in functionality.



* fix: `setup.sh` target container under test

Some of the `setup.sh` commands did not specify the container which was problematic if another `docker-mailserver` container was running, causing test failures.

This probably doesn't help with `test/no_container.bats`, but at least prevents `test/tests.bats` failing at this point.
2022-05-30 12:53:30 +12:00
.github chore: Set permissions for GitHub actions (#2555) 2022-05-11 09:51:15 +02:00
config-examples Add ban feature to fail2ban script (#2538) 2022-04-19 08:44:51 +00:00
docs documentation: DOCKER_HOST missing unix:// (#2595) 2022-05-18 12:18:38 +02:00
target scripts: fix error message caused by grep on first starts (#2591) 2022-05-28 20:59:31 +02:00
test tests(fix): Adjust for local testing conditions (#2606) 2022-05-30 12:53:30 +12:00
.all-contributorsrc Update contributors (#2143) 2021-08-28 15:23:11 +02:00
.dockerignore Update check (#1951) 2021-05-19 21:18:06 +02:00
.editorconfig cleaned up >/dev/nulls in Dockerfile and replaced em dashes with normal dashes (#2024) 2021-06-08 13:20:20 +12:00
.gitignore feat: Support for Dovecot master accounts (#2535) 2022-05-08 00:28:32 +02:00
.gitmodules update bats to latest version 2019-08-05 21:40:09 +02:00
CHANGELOG.md release: v11.0.0 (#2537) 2022-04-27 17:39:18 +02:00
CODE_OF_CONDUCT.md docs(fix): Update wiki references to the new docs url 2021-03-25 11:49:24 +13:00
CONTRIBUTORS.md docs(CONTRIBUTORS): update contributors (#2570) 2022-05-03 13:00:59 +02:00
docker-compose.yml chore: Remove version key from docker-compose.yml (#2271) 2021-10-30 14:12:47 +02:00
Dockerfile feat: Support for Dovecot master accounts (#2535) 2022-05-08 00:28:32 +02:00
LICENSE Final Migration Step (#6) 2021-01-16 10:16:05 +01:00
mailserver.env scripts: added TZ environment variable to set timezone (#2530) 2022-04-06 16:48:41 +02:00
Makefile feat: Support for Dovecot master accounts (#2535) 2022-05-08 00:28:32 +02:00
README.md setup: added grace period for account creation (#2531) 2022-04-18 10:48:48 +02:00
setup.sh Streamline 'printf' usage and consequently use a format string (#2564) 2022-05-05 17:48:21 +02:00
VERSION release: v11.0.0 (#2537) 2022-04-27 17:39:18 +02:00

Docker Mailserver

ci::status docker::pulls documentation::badge

A production-ready fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.). Only configuration files, no SQL database. Keep it simple and versioned. Easy to deploy and upgrade. Documentation via MkDocs.

Originally created by @tomav, docker-mailserver is now maintained by volunteers since January 2021.

If you have issues, read the full README and the documentation for your version (default is edge) first before opening an issue. The issue tracker is for issues, not for personal support.

  1. Included Services
  2. Issues and Contributing
  3. Requirements
  4. Usage
  5. Examples
  6. Environment Variables
  7. Documentation
  8. Release Notes

Included Services

Requirements

Recommended:

  • 1 Core
  • 2GB RAM
  • Swap enabled for the container

Minimum:

  • 1 vCore
  • 512MB RAM
  • 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.

Usage

Available Images / Tags - Tagging Convention

CI/CD will automatically build, test and push new images to container registries. Currently, the following registries are supported:

  1. DockerHub
  2. GitHub Container Registry

All workflows are using the tagging convention listed below. It is subsequently applied to all images.

Event Image Tags
push on master edge
push tag 1.2.3, 1.2, 1, latest

Get the Tools

Since Docker Mailserver v10.2.0, setup.sh functionality is included within the container image. The external convenience script is no longer required if you prefer using docker exec <CONTAINER NAME> setup <COMMAND> instead. If you're new to docker-mailserver, it is recommended to use the script setup.sh for convenience.

DMS_GITHUB_URL='https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master'
wget "${DMS_GITHUB_URL}/docker-compose.yml"
wget "${DMS_GITHUB_URL}/mailserver.env"
wget "${DMS_GITHUB_URL}/setup.sh"
chmod a+x ./setup.sh

Create a docker-compose Environment

  1. Install the latest docker-compose
  2. Edit docker-compose.yml to your liking
    • substitute mail (hostname) and example.com (domainname) according to your FQDN
    • if you want to use SELinux for the ./docker-data/dms/config/:/tmp/docker-mailserver/ mount, append -z or -Z
  3. Configure the mailserver container to your liking by editing mailserver.env (Documentation), but keep in mind this .env file:
    • only basic VAR=VAL is supported (do not quote your values!)
    • variable substitution is not supported (e.g. 🚫 OVERRIDE_HOSTNAME=$HOSTNAME.$DOMAINNAME 🚫)

Note: If you're using podman, make sure to read the related documentation

Get up and running

First Things First

Use docker-compose up / down, not docker-compose start / stop. Otherwise, the container is not properly destroyed and you may experience problems during startup because of inconsistent state.

You are able to get a full overview of how the configuration works by either running:

  1. ./setup.sh help which includes the options of setup.sh.
  2. docker run --rm docker.io/mailserver/docker-mailserver:latest setup help which provides you with all the information on configuration provided "inside" the container itself.

If no docker-mailserver container is running, any ./setup.sh command will check online for the :latest image tag (the current stable release), performing a docker pull ... if necessary followed by running the command in a temporary container.

$ ./setup.sh help
Image 'docker.io/mailserver/docker-mailserver:latest' not found. Pulling ...
SETUP(1)

NAME
    setup - 'docker-mailserver' Administration & Configuration script
...

$ docker run --rm docker.io/mailserver/docker-mailserver:latest setup help
SETUP(1)

NAME
    setup - 'docker-mailserver' Administration & Configuration script
...

Starting for the first time

On first start, you will need to add at least one email account (unless you're using LDAP). You have two minutes to do so, otherwise DMS will shutdown and restart. You can add accounts with the following two methods:

  1. Use setup.sh: ./setup.sh email add <user@domain>
  2. Run the command directly in the container: docker exec -ti <CONTAINER NAME> setup email add <user@domain>

You can then proceed by creating the postmaster alias and by creating DKIM keys.

docker-compose up -d mailserver

# you may add some more users
# for SELinux, use -Z
./setup.sh [-Z] email add <user@domain> [<password>]

# and configure aliases, DKIM and more
./setup.sh [-Z] alias add postmaster@<domain> <user@domain>

Miscellaneous

DNS - DKIM

You can (and you should) generate DKIM keys by running

./setup.sh [-Z] config dkim

If you want to see detailed usage information, run

./setup.sh config dkim help

In case you're using LDAP, the setup looks a bit different as you do not add user accounts directly. Postfix doesn't know your domain(s) and you need to provide it when configuring DKIM:

./setup.sh config dkim domain '<domain.tld>[,<domain2.tld>]'

When keys are generated, you can configure your DNS server by just pasting the content of config/opendkim/keys/domain.tld/mail.txt to set up DKIM. See the documentation for more details.

Custom User Changes & Patches

If you'd like to change, patch or alter files or behavior of docker-mailserver, you can use a script. See the documentation for a detailed explanation.

Updating docker-mailserver

Make sure to read the CHANGELOG before updating to new versions, to be prepared for possible breaking changes.

docker-compose pull
docker-compose down
docker-compose up -d mailserver

You should see the new version number on startup, for example: [ TASKLOG ] Welcome to docker-mailserver 10.1.2.

You're done! And don't forget to have a look at the remaining functions of the setup.sh script with ./setup.sh help.

Supported Operating Systems

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 mail-server in production.

Bare Domains

If you want to use a bare domain (hostname == domainname), see FAQ.

Support for Multiple Domains

docker-mailserver supports multiple domains out of the box, so you can do this:

./setup.sh email add user1@docker.example.com
./setup.sh email add user1@mail.example.de
./setup.sh email add user1@server.example.org

SPF/Forwarding Problems

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.

Ports

See the documentation for further details and best practice advice, especially regarding security concerns.

Mailboxes (aka IMAP Folders)

INBOX is setup by default with the special IMAP folders Drafts, Sent, Junk and Trash. You can learn how to modify or add your own folders (including additional special folders like Archive) by visiting our docs page Customizing IMAP Folders for more information.

Examples

With Relevant Environmental Variables

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. The default docker-compose.yml can be used for the purpose out-of-the-box, see the usage section.

version: '3.8'

services:
  mailserver:
    image: docker.io/mailserver/docker-mailserver:latest
    container_name: mailserver
    hostname: mail
    domainname: example.com
    ports:
      - "25:25"
      - "143:143"
      - "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/
      - /etc/localtime:/etc/localtime:ro
    environment:
      - ENABLE_SPAMASSASSIN=1
      - SPAMASSASSIN_SPAM_TO_INBOX=1
      - ENABLE_CLAMAV=1
      - ENABLE_FAIL2BAN=1
      - ENABLE_POSTGREY=1
      - ENABLE_SASLAUTHD=0
      - ONE_DIR=1
    cap_add:
      - NET_ADMIN
      - SYS_PTRACE
    restart: always

LDAP Setup

Note There are currently no LDAP maintainers. If you encounter issues, please raise them in the issue tracker, but be aware that the core maintainers team will most likely not be able to help you. We would appreciate and we encourage everyone to actively participate in maintaining LDAP-related code by becoming a maintainer!

version: '3.8'

services:
  mailserver:
    image: docker.io/mailserver/docker-mailserver:latest
    container_name: mailserver
    hostname: mail
    domainname: example.com
    ports:
      - "25:25"
      - "143:143"
      - "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/
      - /etc/localtime:/etc/localtime:ro
    environment:
      - ENABLE_SPAMASSASSIN=1
      - SPAMASSASSIN_SPAM_TO_INBOX=1
      - ENABLE_CLAMAV=1
      - ENABLE_FAIL2BAN=1
      - ENABLE_POSTGREY=1
      - ONE_DIR=1
      - 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))
      - POSTMASTER_ADDRESS=postmaster@localhost.localdomain
      - POSTFIX_MESSAGE_SIZE_LIMIT=100000000
    cap_add:
      - NET_ADMIN
      - SYS_PTRACE
    restart: always