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.

#m#y#y#_###aoodAiMuSuDmRTRlXrPrMaeher.dFdArviqeyrooRcesucoemrmC.reoucaeaysisrroiciroestddrnoneu:od.r.crDs-mcdcodNe1a-ooroSt2pim-mdm3ont..a(b.i.ep-iPy4nclrnT5tolee.Ry.smsvmc)o6.eaou7twnim-r.ohtl.8esMh9yraUooAeMsTuTSsuXpXtXTtrtoThTimooemnasfnagie1d1i"t"tlr2e0nvivcp.v3lg=c=hrye.imsaDoor4vaptMyvu5eifiAoirI.rl1oRuddP6.nCreo7eym1rm.moxp;m,a8auoai9ir~lpinnldai=lo.olcqtcmlyusoa"aeDmirrNnavS.nectroimnh.eo;strnuaam=emailto:postmaster@yourdomain.com"

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

  1. Go to Configuration → Configuration & Details → ARC/DKIM keys
  2. Click on your domain
  3. Copy the DKIM public key
  4. Add to DNS:
dkim._domainkey.yourdomain.com.TXT"v=DKIM1;k=rsa;p=MIIBIjANBg..."

Verify:

dig +short TXT dkim._domainkey.yourdomain.com

Step 8: Create Mailbox

  1. Go to Mailboxes → Add mailbox
  2. Local part: you
  3. Domain: yourdomain.com
  4. Full email: [email protected]
  5. Set password
  6. 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:

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:

  1. Go to System → Configuration → Rspamd
  2. Default threshold: 15 (lower = stricter)
  3. 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

  1. Go to Access → Two-Factor Authentication
  2. Scan QR code with authenticator app
  3. 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:

  1. DNS records (SPF, DKIM, DMARC)
  2. Reverse DNS (PTR record)
  3. IP reputation (check blacklists)
  4. Email content (avoid spam trigger words)

Cannot Send Email

Check:

  1. Port 25 not blocked by ISP
  2. Firewall allows ports 25, 587, 993
  3. SMTP logs: docker compose logs postfix-mailcow

Cannot Receive Email

Check:

  1. MX record points to correct server
  2. Port 25 open on firewall
  3. 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):

  1. Mailboxes → Add alias
  2. Forward to existing mailbox

Catch-All Address

Receive all emails to undefined addresses:

  1. Mailboxes → yourdomain.com → Edit
  2. Enable catch-all

Sieve Filters

Create server-side email rules:

  1. Mailboxes → Your mailbox → Sieve filters
  2. 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

  1. Set up backups (daily automation)
  2. Enable 2FA for all accounts
  3. Monitor blacklists weekly
  4. Configure advanced spam filtering
  5. Set up external backup destination

Running Mailcow? Share your experience in the comments!