Mail Server
Initial setup
1 - Updates
sudo apt update && sudo apt upgrade -y
2 - Install docker and docker compose
# Install required packages
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Set up the stable repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add your user to docker group
sudo usermod -aG docker $USER
3 - Create DNS Records
- A record:
mail.yourdomain.com→ your server IP - MX record:
@→mail.yourdomain.com(priority 10) - TXT record (SPF):
v=spf1 mx ~all
4 - Install and configure mailserver
# Create directory for mail server
mkdir -p ~/mailserver
cd ~/mailserver
# Download docker-compose.yml and .env template
wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/compose.yaml
wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/mailserver.env
# Rename for easier use
mv compose.yaml docker-compose.yml
mv mailserver.env .env
5 - Edit .env variables
HOSTNAME=mailDOMAINNAME=yourdomain.comOVERRIDE_HOSTNAME=mail.yourdomain.comENABLE_SPAMASSASSIN=1ENABLE_CLAMAV=1ENABLE_FAIL2BAN=1SSL_TYPE=letsencrypt(ormanualif you have your own certs)ACCOUNT_PROVISIONER=FILE
6 - Edit docker-compose.yml
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mailserver
# Provide the FQDN of your mail server here (Your DNS MX record should point to this value)
hostname: mx.home.conorbriggs.com.au
env_file: .env
# More information about the mail-server ports:
# https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/
ports:
- "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead)
- "143:143" # IMAP4 (explicit TLS => STARTTLS)
- "465:465" # ESMTP (implicit TLS)
- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
volumes:
- ./mail-data/:/var/mail/
- ./mail-state/:/var/mail-state/
- ./mail-logs/:/var/log/mail/
- ./config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
restart: always
stop_grace_period: 1m
# Uncomment if using `ENABLE_FAIL2BAN=1`:
cap_add:
- NET_ADMIN
healthcheck:
test: "ss --listening --ipv4 --tcp | grep --silent ':smtp' || exit 1"
timeout: 3s
retries: 0
networks:
- mailserver-network
networks:
mailserver-network:
driver: bridge
Connecting
IMAP (Incoming):
- Server:
mx.home.conorbriggs.com.au - Port:
993(IMAPS with SSL/TLS) - Security: SSL/TLS
- Authentication: Normal password
SMTP (Outgoing):
- Server:
mx.home.conorbriggs.com.au - Port:
587(with STARTTLS) or465(with SSL/TLS) - Security: STARTTLS (port 587) or SSL/TLS (port 465)
- Authentication: Normal password
Container Management
Basic Container Operations
Start the mailserver
docker compose up -d
Stop the mailserver
docker compose down
Restart the mailserver
docker compose restart
View logs (live)
docker compose logs -f
View logs (last 100 lines)
docker compose logs --tail=100
Check container status
docker ps -a
Check container health
docker inspect mailserver | grep -A 10 Health
Email Account Management
Create Email Accounts
Create a new email account (will prompt for password)
docker exec -it mailserver setup email add user@home.conorbriggs.com.au
Create account with password in command
docker exec -it mailserver setup email add user@home.conorbriggs.com.au password123
Create account with quota (e.g., 500MB)
docker exec -it mailserver setup email add user@home.conorbriggs.com.au password123 500M
List Email Accounts
List all email accounts
docker exec mailserver setup email list
View the accounts file directly
docker exec mailserver cat /tmp/docker-mailserver/postfix-accounts.cf
Update/Change Passwords
Update password for existing account
docker exec -it mailserver setup email update user@home.conorbriggs.com.au new_password
Change password (alternative method - will prompt)
docker exec -it mailserver setup email update user@home.conorbriggs.com.au
Delete Email Accounts
Delete an email account
docker exec -it mailserver setup email del user@home.conorbriggs.com.au
Delete account and remove mailbox data
docker exec mailserver setup email del user@home.conorbriggs.com.au
rm -rf ./mail-data/home.conorbriggs.com.au/user
Alias Management
Create Aliases
Create an alias (forward emails from alias to recipient)
docker exec mailserver setup alias add alias@home.conorbriggs.com.au recipient@home.conorbriggs.com.au
Create alias with multiple recipients
docker exec mailserver setup alias add sales@home.conorbriggs.com.au "user1@home.conorbriggs.com.au,user2@home.conorbriggs.com.au"
List Aliases
List all aliases
docker exec mailserver setup alias list
View aliases file
docker exec mailserver cat /tmp/docker-mailserver/postfix-virtual.cf
Delete Aliases
Delete an alias
docker exec mailserver setup alias del alias@home.conorbriggs.com.au recipient@home.conorbriggs.com.au
Quota Management
Set Quotas
Set quota for a user (e.g., 1GB)
docker exec mailserver setup quota set user@home.conorbriggs.com.au 1G
Set unlimited quota
docker exec mailserver setup quota set user@home.conorbriggs.com.au 0
Check Quotas
Check quota for specific user
docker exec mailserver setup quota get user@home.conorbriggs.com.au
List all quotas
docker exec mailserver setup quota list
Check quota usage
docker exec mailserver doveadm quota get -u user@home.conorbriggs.com.au
Delete Quotas
Remove quota (sets to default)
docker exec mailserver setup quota del user@home.conorbriggs.com.au
DKIM (Email Signing)
Generate DKIM Keys
Generate DKIM key for domain
docker exec mailserver setup config dkim
Generate for specific domain
docker exec mailserver setup config dkim domain home.conorbriggs.com.au
Generate with custom key size
docker exec mailserver setup config dkim keysize 2048
View DKIM Public Key
Show DKIM DNS record
docker exec mailserver setup config dkim help
View the public key directly
docker exec mailserver cat /tmp/docker-mailserver/opendkim/keys/home.conorbriggs.com.au/mail.txt
Fail2Ban (Security)
Fail2Ban Status
Check fail2ban status
docker exec mailserver setup fail2ban status
Check banned IPs
docker exec mailserver setup fail2ban
Unban an IP address
docker exec mailserver setup fail2ban unban <IP_ADDRESS>
Ban an IP address
docker exec mailserver setup fail2ban ban <IP_ADDRESS>
Debugging & Diagnostics
Service Status
Check all listening ports
docker exec mailserver ss -tlnp
Check specific service status
docker exec mailserver supervisorctl status
Check Postfix status
docker exec mailserver postfix status
Check Dovecot status
docker exec mailserver doveadm service status
Mail Queue
View mail queue
docker exec mailserver postqueue -p
Flush mail queue (retry sending)
docker exec mailserver postqueue -f
Delete all queued mail
docker exec mailserver postsuper -d ALL
Delete specific message from queue
docker exec mailserver postsuper -d <QUEUE_ID>
Logs
View mail logs
docker exec mailserver tail -f /var/log/mail/mail.log
View mail errors
docker exec mailserver tail -f /var/log/mail/mail.err
View specific log files
docker exec mailserver ls -la /var/log/mail/
Search logs for specific email
docker exec mailserver grep "user@domain.com" /var/log/mail/mail.log
Test Email Delivery
Test SMTP connection
docker exec mailserver nc -zv localhost 25
Send test email from command line
echo "Test email body" | docker exec -i mailserver sendmail test@home.conorbriggs.com.au
Test with swaks (if installed)
docker exec mailserver swaks --to user@home.conorbriggs.com.au --from test@home.conorbriggs.com.au
Connection Testing
Test IMAP connection
docker exec mailserver nc -zv localhost 143
docker exec mailserver nc -zv localhost 993
Test SMTP connection
docker exec mailserver nc -zv localhost 25
docker exec mailserver nc -zv localhost 587
docker exec mailserver nc -zv localhost 465
Check TLS/SSL certificates
docker exec mailserver openssl s_client -connect localhost:993 -showcerts
docker exec mailserver openssl s_client -connect localhost:465 -showcerts
Configuration Management
Reload Configuration
Reload postfix configuration
docker exec mailserver postfix reload
Reload dovecot configuration
docker exec mailserver doveadm reload
Restart all services
docker compose restart
View Configuration
View postfix configuration
docker exec mailserver postconf
View dovecot configuration
docker exec mailserver doveconf
View specific postfix setting
docker exec mailserver postconf | grep smtp_tls
Check all environment variables
docker exec mailserver env | grep -E '(SMTP|IMAP|SSL|TLS)'
Backup Configuration
Backup all mail data
tar -czf mailserver-backup-$(date +%Y%m%d).tar.gz ./mail-data ./mail-state ./config
Backup just configuration
tar -czf mailserver-config-$(date +%Y%m%d).tar.gz ./config
Backup specific user's mailbox
tar -czf user-backup-$(date +%Y%m%d).tar.gz ./mail-data/home.conorbriggs.com.au/user
Database/User Management
User Database
List all users in Dovecot
docker exec mailserver doveadm user '*'
Check if user exists
docker exec mailserver doveadm user user@home.conorbriggs.com.au
View user's mailbox location
docker exec mailserver doveadm mailbox status -u user@home.conorbriggs.com.au all '*'
Mailbox Management
List mailboxes for user
docker exec mailserver doveadm mailbox list -u user@home.conorbriggs.com.au
Create mailbox for user
docker exec mailserver doveadm mailbox create -u user@home.conorbriggs.com.au Folder.Name
Delete mailbox
docker exec mailserver doveadm mailbox delete -u user@home.conorbriggs.com.au Folder.Name
Rebuild mailbox index
docker exec mailserver doveadm force-resync -u user@home.conorbriggs.com.au INBOX
Performance & Monitoring
Check Resource Usage
Check container stats
docker stats mailserver
Check disk usage
docker exec mailserver df -h
Check memory usage
docker exec mailserver free -h
Check mail directory size
du -sh ./mail-data/*
Connection Monitoring
Show active connections
docker exec mailserver ss -tn | grep -E ':(25|587|465|143|993)'
Count connections by port
docker exec mailserver ss -tn | grep -E ':(25|587|465|143|993)' | wc -l
Show who's connected to IMAP
docker exec mailserver doveadm who
SSL/TLS Certificate Management
Check Certificates
Check SSL certificate expiry
docker exec mailserver openssl x509 -in /etc/letsencrypt/live/mx.home.conorbriggs.com.au/fullchain.pem -noout -dates
View certificate details
docker exec mailserver openssl x509 -in /etc/letsencrypt/live/mx.home.conorbriggs.com.au/fullchain.pem -noout -text
Test SSL/TLS for SMTP
openssl s_client -connect mx.home.conorbriggs.com.au:465 -showcerts
Test STARTTLS for SMTP
openssl s_client -connect mx.home.conorbriggs.com.au:587 -starttls smtp
Troubleshooting
Common Issues
Check if services are running
docker exec mailserver supervisorctl status
Restart specific service
docker exec mailserver supervisorctl restart postfix
docker exec mailserver supervisorctl restart dovecot
Check for permission issues
docker exec mailserver ls -la /var/mail/
docker exec mailserver ls -la /tmp/docker-mailserver/
Verify DNS records
dig mx home.conorbriggs.com.au
dig txt _dmarc.home.conorbriggs.com.au
dig txt mail._domainkey.home.conorbriggs.com.au
Test email authentication
docker exec mailserver opendkim-testkey -d home.conorbriggs.com.au -s mail
Reset and Clean Up
Remove all mail data (WARNING: deletes all emails)
docker compose down
rm -rf ./mail-data/*
rm -rf ./mail-state/*
docker compose up -d
Clear logs
docker exec mailserver truncate -s 0 /var/log/mail/mail.log
Rebuild entire container
docker compose down
docker compose pull
docker compose up -d --force-recreate
Quick Reference
Setup Script Help
Show all setup commands
docker exec mailserver setup help
Help for specific command
docker exec mailserver setup email help
docker exec mailserver setup alias help
docker exec mailserver setup config help
File Locations Inside Container
/tmp/docker-mailserver/ - Configuration files (mapped to ./config/)
/var/mail/ - Mail data (mapped to ./mail-data/)
/var/mail-state/ - State files (mapped to ./mail-state/)
/var/log/mail/ - Mail logs (mapped to ./mail-logs/)
/etc/letsencrypt/ - SSL certificates (read-only)
/etc/postfix/ - Postfix configuration
/etc/dovecot/ - Dovecot configuration
Important Configuration Files
./config/postfix-accounts.cf - Email accounts
./config/postfix-virtual.cf - Aliases
./config/dovecot-quotas.cf - User quotas
./config/opendkim/ - DKIM keys
Advanced Operations
Database Operations
Export all accounts
docker exec mailserver cat /tmp/docker-mailserver/postfix-accounts.cf > accounts-backup.txt
Import accounts
cat accounts-backup.txt | docker exec -i mailserver tee /tmp/docker-mailserver/postfix-accounts.cf
docker compose restart
Verify account database
docker exec mailserver postmap -q user@home.conorbriggs.com.au /tmp/docker-mailserver/postfix-accounts.cf
Custom Scripts
Run custom maintenance script
docker exec mailserver /bin/bash -c "your-script-here"
Execute interactive shell
docker exec -it mailserver /bin/bash
Monitoring & Alerts
Set Up Monitoring
Watch logs in real-time
docker compose logs -f --tail=100
Monitor for failed logins
docker exec mailserver tail -f /var/log/mail/mail.log | grep "authentication failed"
Monitor mail queue size
watch -n 60 'docker exec mailserver postqueue -p | tail -1'
Check for errors
docker exec mailserver grep -i error /var/log/mail/mail.log | tail -20
Common Workflows
Adding a New User
1. Create account
docker exec -it mailserver setup email add newuser@home.conorbriggs.com.au
2. Set quota (optional)
docker exec mailserver setup quota set newuser@home.conorbriggs.com.au 2G
3. Verify account created
docker exec mailserver setup email list
4. Test login: Use an email client to connect via IMAP (993) or SMTP (587)
Migrating Mail
1. Backup old server
tar -czf old-mailserver-backup.tar.gz ./mail-data
2. Copy to new server
scp old-mailserver-backup.tar.gz newserver:/path/to/mailserver/
3. Extract on new server
tar -xzf old-mailserver-backup.tar.gz
4. Fix permissions
chown -R 5000:5000 ./mail-data
5. Restart mailserver
docker compose restart
Security Hardening
1. Enable Fail2Ban (in .env file)
ENABLE_FAIL2BAN=1
2. Check banned IPs regularly
docker exec mailserver fail2ban-client status postfix-sasl
3. Monitor authentication attempts
docker exec mailserver grep "authentication failed" /var/log/mail/mail.log
4. Review SSL/TLS settings
docker exec mailserver postconf | grep tls
Tips & Best Practices
- Always backup before major changes:
tar -czf backup.tar.gz ./mail-data ./config - Test email flow after changes: Send test emails in/out
- Monitor disk space: Check
df -hregularly - Keep certificates updated: Let's Encrypt certs expire every 90 days
- Review logs periodically: Look for authentication failures or delivery issues
- Set appropriate quotas: Prevent users from filling up disk
- Use strong passwords: Minimum 12 characters for email accounts
- Enable DKIM/SPF/DMARC: Improves deliverability
- Regular updates:
docker compose pull && docker compose up -d - Document your changes: Keep notes on custom configurations