Running your own email server is one of the most challenging self-hosting projects. But with Mailcow, it’s actually manageable.
This guide shows you how to set up a complete, production-ready email server with Mailcow—handling everything from DNS to spam filtering to webmail.
Why Self-Host Email?
Pros:
- Complete control over your data
- Custom domain email ([email protected])
- No storage limits
- No scanning of your emails
- Learning experience
Cons:
- Complex setup
- Requires dedicated server with static IP
- Deliverability challenges (avoiding spam folders)
- Ongoing maintenance required
Reality Check: Self-hosting email is hard. Gmail and Proton Mail exist for good reasons. Only do this if you understand the commitment.
Prerequisites
Required:
- Dedicated server with static public IP (no dynamic IPs, no residential ISP)
- Domain name with full DNS control
- 2GB+ RAM minimum (4GB recommended)
- 20GB+ storage
- Port 25 NOT blocked by ISP (most cloud providers block this—check first!)
Providers that allow port 25:
- Hetzner (Germany)
- OVH
- Vultr (some regions)
- DigitalOcean (request unblock)
Providers that DON’T allow port 25:
- AWS EC2 (requires forms/justification)
- Google Cloud
- Azure
- Most residential ISPs
Architecture Overview
Mailcow includes:
- Postfix - SMTP server (sending/receiving)
- Dovecot - IMAP/POP3 (email storage)
- Rspamd - Spam filtering
- SOGo - Webmail interface
- ClamAV - Antivirus
- Redis, MySQL - Databases
- Nginx - Web server
All run in Docker containers, managed together.
Step 1: Server Setup
# Update system
apt update && apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com | sh
# Install Docker Compose
apt install docker-compose-plugin -y
# Create mailcow user (optional but recommended)
useradd -m -s /bin/bash mailcow
usermod -aG docker mailcow
su - mailcow
Step 2: DNS Configuration
Critical: Get DNS right FIRST. Email won’t work otherwise.
Required DNS Records
Replace mail.yourdomain.com with your mail server hostname.
DKIM will be generated after Mailcow installation.
Verify DNS
# Check MX record
dig +short MX yourdomain.com
# Check A record
dig +short mail.yourdomain.com
# Check SPF
dig +short TXT yourdomain.com
Step 3: Install Mailcow
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
# Generate configuration
./generate_config.sh
You’ll be asked:
- Mail server hostname:
mail.yourdomain.com - Timezone:
America/New_York(or your timezone)
Step 4: Configure Mailcow
Edit mailcow.conf:
nano mailcow.conf
Important settings:
# Hostname (FQDN)
MAILCOW_HOSTNAME=mail.yourdomain.com
# Timezone
TZ=America/New_York
# HTTP/HTTPS ports (change if needed)
HTTP_PORT=80
HTTPS_PORT=443
# Let's Encrypt (enable for SSL)
SKIP_LETS_ENCRYPT=n
# Admin password (change this!)
# Leave blank to auto-generate
Step 5: Start Mailcow
docker compose pull
docker compose up -d
Wait 5-10 minutes for all containers to start and initialize.
Check status:
docker compose ps
All services should be “Up” and healthy.
Step 6: Initial Setup
Access web admin: https://mail.yourdomain.com
Default credentials:
- Username:
admin - Password:
moohoo
CHANGE THE PASSWORD IMMEDIATELY
Step 7: Add DKIM Record
- Go to Configuration → Configuration & Details → ARC/DKIM keys
- Click on your domain
- Copy the DKIM public key
- Add to DNS:
Verify:
dig +short TXT dkim._domainkey.yourdomain.com
Step 8: Create Mailbox
- Go to Mailboxes → Add mailbox
- Local part:
you - Domain:
yourdomain.com - Full email:
[email protected] - Set password
- Click Add
Step 9: Test Email Sending
Use webmail at https://mail.yourdomain.com/SOGo
Send a test email to Gmail or another service.
Check spam score:
- Send to:
[email protected] - You’ll receive a detailed report
Step 10: Configure Email Client
Use these settings in Thunderbird, Outlook, or mobile:
IMAP (Receiving):
- Server:
mail.yourdomain.com - Port:
993 - Security: SSL/TLS
- Username:
[email protected] - Password: (your mailbox password)
SMTP (Sending):
- Server:
mail.yourdomain.com - Port:
587 - Security: STARTTLS
- Username:
[email protected] - Password: (your mailbox password)
Spam Filtering Configuration
Mailcow uses Rspamd for spam filtering.
Adjust spam threshold:
- Go to System → Configuration → Rspamd
- Default threshold: 15 (lower = stricter)
- Recommended: 7-10 for personal use
Greylisting:
- Enabled by default
- Delays first-time senders by 5 minutes
- Reduces spam significantly
Security Hardening
Enable Two-Factor Authentication
- Go to Access → Two-Factor Authentication
- Scan QR code with authenticator app
- Enable 2FA
Restrict Admin Access
# Edit mailcow.conf
nano mailcow.conf
# Add allowed IPs
ADMIN_IP_RANGE=192.168.1.0/24,your.public.ip
Restart:
docker compose down && docker compose up -d
Enable Fail2Ban
Mailcow has built-in fail2ban:
# Check status
docker compose exec fail2ban-mailcow fail2ban-client status
Bans IPs after failed login attempts.
Backup Strategy
Automated Backup
Mailcow includes backup script:
cd /opt/mailcow-dockerized
./helper-scripts/backup_and_restore.sh backup all
Schedule daily backups:
crontab -e
# Add:
0 2 * * * cd /opt/mailcow-dockerized && ./helper-scripts/backup_and_restore.sh backup all
What Gets Backed Up
- Mail data (all emails)
- MySQL databases
- Redis data
- Rspamd configuration
- SSL certificates
Restore from Backup
./helper-scripts/backup_and_restore.sh restore
Monitoring & Maintenance
Check Mail Queue
docker compose exec postfix-mailcow mailq
Empty queue = good. Stuck emails = investigate logs.
View Logs
# All containers
docker compose logs -f
# Specific service
docker compose logs -f postfix-mailcow
docker compose logs -f dovecot-mailcow
Update Mailcow
cd /opt/mailcow-dockerized
./update.sh
Run monthly or when security updates are announced.
Deliverability Tips
Warm Up Your IP
Don’t send 1000 emails on day one. Gradually increase volume:
- Week 1: 10-20 emails/day
- Week 2: 50-100 emails/day
- Week 3: 200+ emails/day
Monitor Reputation
Check your IP and domain reputation:
Avoid Blacklists
- Don’t send spam (obvious but critical)
- Set up DKIM, SPF, DMARC correctly
- Monitor for compromised accounts
- Enable rate limiting
Troubleshooting
Emails Going to Spam
Check:
- DNS records (SPF, DKIM, DMARC)
- Reverse DNS (PTR record)
- IP reputation (check blacklists)
- Email content (avoid spam trigger words)
Cannot Send Email
Check:
- Port 25 not blocked by ISP
- Firewall allows ports 25, 587, 993
- SMTP logs:
docker compose logs postfix-mailcow
Cannot Receive Email
Check:
- MX record points to correct server
- Port 25 open on firewall
- Postfix logs:
docker compose logs postfix-mailcow
Common Issues
“Connection Refused” on Port 25
Your ISP blocks port 25. Switch to a provider that doesn’t.
Emails from Gmail Going to Spam
Gmail is strict. Ensure:
- PTR record matches hostname
- DKIM signature valid
- SPF passes
- Gradually build reputation
High CPU Usage
ClamAV virus scanning uses CPU. Disable if not needed:
nano docker-compose.override.yml
# Add:
services:
clamd-mailcow:
entrypoint: ["echo", "Service disabled"]
Advanced Features
Aliases & Forwarding
Create email aliases (e.g., support@ → your main inbox):
- Mailboxes → Add alias
- Forward to existing mailbox
Catch-All Address
Receive all emails to undefined addresses:
- Mailboxes → yourdomain.com → Edit
- Enable catch-all
Sieve Filters
Create server-side email rules:
- Mailboxes → Your mailbox → Sieve filters
- Add rules (move to folder, mark as read, etc.)
Alternatives to Mailcow
- Mail-in-a-Box - Simpler but less features
- iRedMail - Older, still maintained
- Mailu - Lighter weight
- Docker Mailserver - More manual configuration
Why Mailcow? Best balance of features, ease of use, and active development.
Conclusion
Self-hosting email with Mailcow is achievable if you:
- Have a proper server (static IP, port 25 allowed)
- Configure DNS correctly
- Follow security best practices
- Commit to ongoing maintenance
It’s not for everyone, but if you want full control over your email, Mailcow is the way.
Next Steps
- Set up backups (daily automation)
- Enable 2FA for all accounts
- Monitor blacklists weekly
- Configure advanced spam filtering
- Set up external backup destination
Running Mailcow? Share your experience in the comments!