Self-Hosting Email with Mailcow: A Complete Docker Mail Server
Running your own email server is one of the most ambitious self-hosting projects you can take on. The upside is complete control over your communications — no third party reading your mail, no storage limits, no vendor lock-in. The downside is that email is a notoriously complex protocol where one misconfiguration means your messages land in spam folders or never arrive at all.
Photo by Adam Cheek on Unsplash
Mailcow is a Docker-based mail server suite that bundles everything you need — SMTP, IMAP, webmail, spam filtering, antivirus, and administration — into a single docker compose deployment. It removes much of the pain of configuring Postfix and Dovecot by hand while still giving you full control.

Why Self-Host Email?
Before investing the time, consider whether self-hosted email is right for you:
- Privacy — Your emails stay on your hardware. No advertising profiles built from your inbox.
- Control — You set the rules. Custom domains, unlimited aliases, no arbitrary attachment size limits.
- Learning — Understanding email infrastructure (DNS, TLS, authentication) is valuable knowledge for any sysadmin.
- Independence — No risk of a provider shutting down your account or changing their terms overnight.
The honest counterpoint: major providers like Gmail and Outlook have massive deliverability advantages. Your self-hosted server will need careful DNS configuration and a clean IP reputation to avoid being treated as spam. This is solvable, but it requires ongoing attention.
What Mailcow Includes
Mailcow is not a single application — it is an orchestrated stack of proven open-source components:
- Postfix — The SMTP server that handles sending and receiving email
- Dovecot — The IMAP/POP3 server that stores mail and serves it to your clients
- SOGo — A full-featured webmail client with calendar and contacts (ActiveSync support for mobile devices)
- rspamd — Spam filtering with Bayesian learning, greylisting, and DKIM signing
- ClamAV — Antivirus scanning for attachments
- Nginx — Reverse proxy for the web interface
- MySQL (MariaDB) — Stores user accounts, domains, and configuration
- Unbound — Local DNS resolver for DNSSEC validation
- PHP-FPM — Powers the Mailcow admin UI
All of these run as separate Docker containers managed by a single docker-compose.yml. You interact with them through Mailcow's web admin panel rather than editing config files directly.
Prerequisites
Before deploying Mailcow, you need:
- A VPS or dedicated server with a static IP address (not behind CGNAT). Most residential ISPs block port 25, so a VPS is strongly recommended.
- A clean IP address — Check your IP against blacklists at MXToolbox before starting. A blacklisted IP means your email goes straight to spam.
- A domain name with full DNS control
- Docker and Docker Compose installed
- At least 4 GB RAM — ClamAV alone needs about 1 GB. You can disable it to run on less, but you lose antivirus scanning.
- Ports 25, 80, 143, 443, 465, 587, 993, 4190 available and not blocked by your hosting provider
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
Docker Deployment
Clone and configure
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh
The generate_config.sh script asks for your mail server hostname (e.g., mail.yourdomain.com) and timezone, then generates a mailcow.conf file. Review it before proceeding:
# Key settings in mailcow.conf
MAILCOW_HOSTNAME=mail.yourdomain.com
MAILCOW_PASS_SCHEME=BLF-CRYPT
DBNAME=mailcow
DBUSER=mailcow
SKIP_CLAMD=n # Set to y to disable ClamAV (saves ~1 GB RAM)
SKIP_SOLR=y # Solr full-text search (resource heavy, optional)
Start the stack
docker compose pull
docker compose up -d
The first startup takes several minutes as ClamAV downloads its virus definitions. Monitor progress with:
docker compose logs -f
Once everything is running, access the admin interface at https://mail.yourdomain.com. The default credentials are admin / moohoo — change these immediately.
DNS Configuration
DNS is the most critical part of a mail server setup. Incorrect DNS means your emails will be rejected or flagged as spam by every major provider. You need all of the following records.
MX record
Tells the world where to deliver email for your domain:
yourdomain.com. IN MX 10 mail.yourdomain.com.
A and AAAA records
Point your mail hostname to your server:
mail.yourdomain.com. IN A 203.0.113.10
mail.yourdomain.com. IN AAAA 2001:db8::1
Reverse DNS (PTR)
Your VPS provider must set the PTR record for your IP to match your mail hostname. This is configured in your hosting provider's control panel, not your DNS zone. Without a matching PTR record, many servers will reject your email outright.
203.0.113.10 IN PTR mail.yourdomain.com.
SPF record
Specifies which servers are authorized to send email for your domain:
yourdomain.com. IN TXT "v=spf1 mx a -all"
This says: only your MX server and A record are allowed to send mail. The -all (hard fail) tells receivers to reject anything from other sources.
DKIM record
Mailcow generates DKIM keys automatically. After adding your domain in the admin panel, navigate to Configuration > Domains > DNS to find your DKIM public key. Add it as a TXT record:
dkim._domainkey.yourdomain.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."
DMARC record
Ties SPF and DKIM together and tells receivers what to do with failing messages:
_dmarc.yourdomain.com. IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]; adkim=s; aspf=s"
Start with p=none while testing, then move to p=quarantine, and finally p=reject once you have confirmed everything works.
Basic Administration
Adding domains and mailboxes
- Log into the admin UI at
https://mail.yourdomain.com - Go to Configuration > Mail Setup > Domains and add your domain
- After adding the domain, go to Mailboxes and create user accounts
- Check the DNS tab for each domain to verify all records are correct — Mailcow shows green checkmarks when everything is properly configured
Spam filter tuning
rspamd handles spam filtering with sensible defaults. Access the rspamd UI at https://mail.yourdomain.com/rspamd/ to:
- View spam scores for recent messages
- Train the Bayesian filter by marking messages as spam or ham
- Adjust scoring thresholds
- Whitelist or blacklist specific senders
Security Hardening
A mail server is a high-value target. Take these steps beyond the defaults:
Change default credentials
Immediately after first login, change the admin password. Also change the database passwords in mailcow.conf and restart the stack.
Enable two-factor authentication
The Mailcow admin panel supports TOTP (time-based one-time passwords). Enable it under System > Admin > Two-Factor Authentication.
Limit admin access
Use a firewall to restrict access to the admin panel (port 443) to your IP addresses only. Email ports (25, 465, 587, 993) should remain open to the world.
# Example: restrict web admin to your IP only
ufw allow from 198.51.100.5 to any port 443
ufw allow 25/tcp
ufw allow 465/tcp
ufw allow 587/tcp
ufw allow 993/tcp
Keep the stack updated
Mailcow provides a built-in update mechanism:
cd /opt/mailcow-dockerized
./update.sh
Run this regularly. Email server vulnerabilities are actively exploited, and Mailcow publishes security updates frequently.
Backup your data
Mailcow includes a backup script:
cd /opt/mailcow-dockerized
./helper-scripts/backup_and_restore.sh backup all
Automate this with a cron job and store backups off-server. Your email data is irreplaceable.
Monitor your IP reputation
Regularly check your server IP against blacklists. If you land on one (often due to a compromised account sending spam), you need to identify the cause, fix it, and request delisting. Services like MXToolbox and mail-tester.com help you monitor deliverability.
Testing Your Setup
Before relying on your server for real email, verify everything works:
- Send a test email to an external address (Gmail, Outlook) and check the headers — look for
spf=pass,dkim=pass, anddmarc=pass - Use mail-tester.com — Send an email to the address they provide and get a deliverability score. Aim for 10/10.
- Test receiving — Send from Gmail to your server and confirm delivery
- Check your DNS — Use
digor MXToolbox to verify all records resolve correctly - Test autoconfig — Try adding your account in Thunderbird or a mobile client and confirm it auto-discovers settings
The Honest Trade-offs
Mailcow is the right choice if:
- You want a complete, production-ready mail server without configuring each component by hand
- You're comfortable with Docker and basic Linux administration
- You have a VPS with a clean IP address and open mail ports
- You want webmail, spam filtering, and antivirus out of the box
Mailcow is not ideal if:
- You just need email forwarding (use a simple relay instead)
- You're on a low-memory VPS with less than 2 GB RAM
- You don't want the responsibility of monitoring deliverability and IP reputation
- You need guaranteed inbox delivery for transactional business email (use a dedicated provider like Postmark for that)
Verdict
Mailcow is the most complete self-hosted email solution available today. It takes the dozens of components required for a proper mail server — SMTP, IMAP, webmail, spam filtering, antivirus, DKIM signing, admin interface — and bundles them into a deployment you can have running in under an hour.
The catch is that running a mail server is an ongoing commitment. DNS must be correct, your IP must stay clean, and you need to keep the stack updated. But if you accept that responsibility, Mailcow gives you something no hosted provider can: complete ownership of your email infrastructure, with no one between you and your inbox.
Resources
- Mailcow documentation
- Mailcow GitHub
- mail-tester.com — Test your email deliverability score
- MXToolbox — DNS, blacklist, and SMTP diagnostics
- learndmarc.com — Interactive tool for understanding DMARC, SPF, and DKIM
