Why Self-Host Email?
Google Workspace costs $7-18 per user per month. For small teams, self-hosting email can save significant money. However, email self-hosting requires careful configuration to ensure deliverability. This guide covers the full migration process.
Choose Your Mail Server
- Mail-in-a-Box: All-in-one solution, easiest setup
- Mailcow: Docker-based, feature-rich with SOGo webmail
- Postal: Designed for transactional and bulk email
- Postfix + Dovecot: Manual setup, most flexible
Set Up Mail Server (Mailcow Example)
# Prerequisites: VPS with 4GB+ RAM, clean IP, rDNS configured
# Install Docker
curl -fsSL https://get.docker.com | bash
# Install Mailcow
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh
# Enter your mail hostname: mail.example.com
docker compose pull
docker compose up -d
# Access: https://mail.example.com
# Default login: admin / moohoo
Configure DNS Records
# Essential DNS records (add to your DNS provider):
# MX record:
example.com MX 10 mail.example.com
# A record for mail server:
mail.example.com A YOUR_SERVER_IP
# SPF:
example.com TXT "v=spf1 ip4:YOUR_IP mx -all"
# DKIM: (generated by Mailcow, copy from admin panel)
dkim._domainkey.example.com TXT "v=DKIM1; k=rsa; p=..."
# DMARC:
_dmarc.example.com TXT "v=DMARC1; p=quarantine; rua=mailto:postmaster@example.com"
# rDNS (reverse DNS): Set via your VPS provider
# YOUR_IP should resolve to mail.example.com
Create Mailboxes
# In Mailcow admin:
# 1. Add domain: example.com
# 2. Create mailboxes for each user
# 3. Set passwords and quotas
# 4. Configure aliases if needed
Migrate Mailboxes from Google
# Install imapsync
sudo apt install -y imapsync
# For each user, sync their Google mailbox:
imapsync \
--host1 imap.gmail.com --port1 993 --ssl1 \
--user1 "user@example.com" --password1 "google-app-password" \
--host2 mail.example.com --port2 993 --ssl2 \
--user2 "user@example.com" --password2 "new-password" \
--gmail1 \
--exclude "\[Gmail\]/All Mail" \
--exclude "\[Gmail\]/Spam"
# Generate Google App Password:
# Google Account > Security > App passwords
# Select Mail, generate password
# For bulk migration, create a script:
while IFS=, read -r email google_pass new_pass; do
imapsync --host1 imap.gmail.com --ssl1 --user1 "$email" \
--password1 "$google_pass" --gmail1 \
--host2 mail.example.com --ssl2 --user2 "$email" \
--password2 "$new_pass"
done < users.csv
Update MX Records
# Only update MX records AFTER:
# 1. All mailboxes are migrated
# 2. DNS records (SPF, DKIM, DMARC) are verified
# 3. Test sending and receiving on the new server
# Remove Google MX records and add your server
# Old: ASPMX.L.GOOGLE.COM (and alt MX records)
# New: mail.example.com (priority 10)
Post-Migration
- Test sending email to Gmail, Outlook, and Yahoo to verify deliverability
- Check spam scores at mail-tester.com
- Configure client apps (Thunderbird, Outlook, mobile) with new IMAP/SMTP settings
- Set up automated backups for mail data
- Monitor mail logs for delivery issues
- Keep Google Workspace active for 30 days as fallback