DO

Docker Mailserver

Production-ready, config-driven mail server in a container

Mail Servers ★ 18.9k stars Medium setup MIT

Docker Mailserver is a single-container mail server built on Postfix and Dovecot with no external database. It is configured entirely through files and environment variables for a reproducible setup.

Key features

  • Single container, no database
  • Postfix and Dovecot core
  • SpamAssassin and ClamAV integration
  • File-based configuration

Pros & cons

Strengths

  • Reproducible, version-controllable config
  • Lightweight

Trade-offs

  • No built-in webmail
  • Requires comfort with mail concepts

Docker Mailserver replaces

Last reviewed Aug 26, 2026 · 900 words

The container is the easy 20 percent. Docker Mailserver packages Postfix, Dovecot, Rspamd or SpamAssassin, ClamAV and Fail2ban into one image with no database and a directory of config files, and it will be receiving mail within an hour. Whether anyone receives yours depends on the other 80 percent: a host whose provider allows outbound port 25, a reverse DNS record that matches your hostname, and SPF, DKIM and DMARC records that all agree. If you cannot get those, no mail server will save you, and the honest take on self-hosted email is the place to decide whether to continue.

It is a mail server, not a mail suite

Docker Mailserver deliberately does nothing but SMTP and IMAP. There is no webmail, no calendar, no admin panel; accounts are lines in postfix-accounts.cf managed with a setup script, and every setting is an environment variable. That is why it fits in the 2 GB minimum and why the whole configuration can live in git and be rebuilt on a new host in minutes. It is also why people coming from Gmail or Google Workspace get a shock: reading mail needs a client such as Thunderbird, or a separate webmail container like Roundcube or SnappyMail. Groupware bundles like mailcow exist for people who want the panel and the webmail included, at roughly 2 to 3 times the memory.

The compose file and the two commands that matter

services:
  mailserver:
    image: ghcr.io/docker-mailserver/docker-mailserver:latest
    hostname: mail.example.com
    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/
      - /etc/localtime:/etc/localtime:ro
    environment:
      - ENABLE_RSPAMD=1
      - ENABLE_CLAMAV=1
      - ENABLE_FAIL2BAN=1
      - SSL_TYPE=letsencrypt
      - PERMIT_DOCKER=none
    cap_add:
      - NET_ADMIN
    restart: always

The hostname is not decoration; Postfix announces it in every SMTP conversation and receiving servers compare it with your reverse DNS. After docker compose up -d:

docker exec -it mailserver setup email add [email protected]
docker exec -it mailserver setup config dkim

The second command writes a DKIM key into the config directory and prints the DNS record to publish. Turn ClamAV off if you are tight on memory; it alone accounts for most of the 2 GB. SSL_TYPE=letsencrypt expects certificates mounted from a Caddy, Traefik or certbot volume; the TLS post covers getting them without drama.

Port 25 and reverse DNS are the gate, and the VPS decides

Almost every residential ISP blocks outbound port 25, so a homelab can receive mail but not send it directly. Several large cloud providers block it on new accounts as well and require a ticket to open it. Before you spend a weekend on this, run nc -zv gmail-smtp-in.l.google.com 25 from the intended host. If it hangs, pick a different host, or accept relaying outbound through a transactional SMTP provider (Docker Mailserver supports this with a few RELAY_ variables) while receiving directly. Then set the PTR record for the host's IP to mail.example.com in the provider's panel; this is the one record you cannot set in your own DNS zone and the one big providers check first.

Four DNS records, then a test

MX pointing at mail.example.com. An SPF TXT on the domain, v=spf1 mx -all if the server is the only sender. The DKIM TXT that setup config dkim printed. A DMARC TXT at _dmarc.example.com, starting with v=DMARC1; p=none; rua=mailto:[email protected] so you get reports before you enforce anything. Send a message to a Gmail address and open "show original": all three of SPF, DKIM and DMARC should read PASS. Then send one to a Microsoft address, because Outlook's reputation rules are stricter and a new IP frequently lands in junk there for weeks regardless of correct records. A new IP with no history is the biggest deliverability risk, and only time and volume fix it.

Backups and updates are unglamorous and mandatory

Everything is in the docker-data/dms tree: mail in mail-data, Rspamd and Dovecot state in mail-state, DKIM keys and account files in config. Snapshot the whole tree nightly, and keep the config directory in a private git repo, because it is the reproducible half of the setup. Updates are a docker compose pull and a restart; read the release notes first, as major versions have changed variable names. Fail2ban with NET_ADMIN is on in the compose above and is the reason the auth log stays readable.

What I'd do

A 4 to 6 dollar VPS with a clean IP and confirmed port 25, Docker Mailserver with Rspamd, ClamAV off unless you have RAM to spare, Roundcube beside it for the household, and certificates from Caddy. Publish all four DNS records and the PTR before the first outbound message. Keep Gmail forwarding to it for a month while the reputation settles. For one domain and a handful of mailboxes, it is the most maintainable self-hosted mail I have run; for a family that wants a webmail panel and calendars out of the box, take mailcow instead and pay for it in memory.

Compare Docker Mailserver

9 head-to-head comparisons.

Similar mail servers apps