Complete Guide to Setting Up Mailu Email Server on Debian for Personal Domain
Introduction
Welcome to the definitive guide for setting up your own private email server using Mailu on Debian. As Sugan Siddhant Dodrai, I understand the importance of having complete control over your digital communications. This comprehensive 10,000-word guide will walk you through every step of creating a professional, secure email server for your personal domain.
Why Run Your Own Email Server?
Before we dive into the technical setup, let's explore why self-hosted email matters:
Privacy & Control: Your data remains yours
Brand Identity: Professional emails with your domain
No Limitations: Avoid storage restrictions and sending limits
Cost-Effective: Long-term savings over hosted solutions
Learning Experience: Valuable sysadmin skills
Prerequisites
Hardware Requirements
Minimum: 2GB RAM, 2 CPU cores, 20GB storage
Recommended: 4GB RAM, 4 CPU cores, 50GB storage
Storage: SSD highly recommended for database performance
Software Requirements
Debian 11 (Bullseye) or Debian 12 (Bookworm)
Docker and Docker Compose
Domain name with DNS access
Static IP address (or dynamic DNS solution)
Domain Preparation
Purchase a domain (if you haven't already)
Ensure you have access to DNS management
Decide on your primary domain (e.g., yourdomain.com)
Part 1: Initial Server Setup
Step 1: Debian Installation and Updates
# Update package listssudo apt update && sudo apt upgrade -y# Install essential packagessudo apt install -y curl wget git vim htop net-tools \ufw fail2ban gnupg software-properties-common# Set your hostnamesudo hostnamectl set-hostname mail.yourdomain.com# Update /etc/hostsecho "127.0.0.1 mail.yourdomain.com" | sudo tee -a /etc/hosts
Step 2: Create a Non-Root User
# Create new usersudo adduser sugansudo usermod -aG sudo sugan# Switch to new usersu - sugan
Step 3: Configure SSH Security
# Edit SSH configurationsudo vim /etc/ssh/sshd_config# Important changes:# Port 2222 (change from default 22)# PermitRootLogin no# PasswordAuthentication no (use SSH keys)# AllowUsers sugan# Restart SSHsudo systemctl restart sshd
Step 4: Configure Firewall
# Enable UFWsudo ufw enable# Allow essential portssudo ufw allow 2222/tcp # SSHsudo ufw allow 80/tcp # HTTPsudo ufw allow 443/tcp # HTTPSsudo ufw allow 25/tcp # SMTPsudo ufw allow 587/tcp # Submissionsudo ufw allow 465/tcp # SMTPSsudo ufw allow 143/tcp # IMAPsudo ufw allow 993/tcp # IMAPSsudo ufw allow 110/tcp # POP3sudo ufw allow 995/tcp # POP3S# Verify rulessudo ufw status verbose
Step 5: Install Docker and Docker Compose
# Install Docker dependenciessudo apt install -y apt-transport-https ca-certificates \curl gnupg lsb-release# Add Docker GPG keycurl -fsSL https://download.docker.com/linux/debian/gpg | \sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg# Add Docker repositoryecho "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 Dockersudo apt updatesudo apt install -y docker-ce docker-ce-cli containerd.io# Install Docker Composesudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" \-o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-compose# Add user to docker groupsudo usermod -aG docker sugan# Enable Docker to start on bootsudo systemctl enable dockersudo systemctl start docker# Verify installationdocker --versiondocker-compose --version
Part 2: Mailu Setup
Step 6: Install Mailu Configuration Wizard
# Create Mailu directorymkdir ~/mailu && cd ~/mailu# Download the setup wizardcurl -O https://setup.mailu.io/1.11/master# Make it executablechmod +x master# Run the setup wizard./master
Step 7: Mailu Configuration
During the wizard, you'll need to make these choices:
Mailu version: 1.11 (stable)
Storage path:
/mailuMain mail domain:
yourdomain.comServer hostname:
mail.yourdomain.comAuthentication: We'll choose
frontfor integrated authentication- TLS certificate:
letsencrypt Timezone: Your timezone (e.g., Asia/Kolkata)
Webmail:
roundcube(recommended)Database:
mysql(or postgresql if preferred)Message size limit: Set according to your needs (e.g., 50M)
Step 8: Configure docker-compose.yml
After the wizard completes, you'll have a docker-compose.yml file. Let's examine and customize it:
version: '3.8'services:# Frontend servicefront:image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}nginx:${MAILU_VERSION:-1.11}restart: alwaysenv_file: .envports:- "80:80"- "443:443"- "25:25"- "465:465"- "587:587"- "993:993"- "995:995"volumes:- "/mailu/certs:/certs"- "/mailu/overrides:/overrides"depends_on:- admin- imap# Admin interfaceadmin:image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}admin:${MAILU_VERSION:-1.11}restart: alwaysenv_file: .envvolumes:- "/mailu/data:/data"- "/mailu/dkim:/dkim"# IMAP serviceimap:image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}dovecot:${MAILU_VERSION:-1.11}restart: alwaysenv_file: .envvolumes:- "/mailu/mail:/mail"- "/mailu/overrides:/overrides"# Add other services as needed...
Step 9: Configure .env File
The .env file contains crucial configuration. Let's review and customize:
# Open the .env filevim .env
Key configurations to verify:
# Domain settingsDOMAIN=yourdomain.comHOSTNAME=mail.yourdomain.com# TLS settings TLS_FLAVOR=letsencrypt # Secret keys (generate unique ones) SECRET_KEY=your-secure-random-key-here DB_PW=your-secure-database-password # Admin settings [email protected] INITIAL_ADMIN_PW=secure-admin-password # Mail settingsMESSAGE_SIZE_LIMIT=50000000 # 50MB
Generate secure passwords:
# Generate random secret keyopenssl rand -hex 32# Generate database passwordopenssl rand -base64 32
Step 10: Create Required Directories and Set Permissions
# Create directory structuresudo mkdir -p /mailu/{data,dkim,certs,mail,overrides,redis}# Set proper permissionssudo chown -R 1000:1000 /mailu/datasudo chown -R 1000:1000 /mailu/dkimsudo chown -R 1000:1000 /mailu/mail# Set permissions for certs directorysudo chmod 755 /mailu/certs
Part 3: DNS Configuration
Step 11: Configure DNS Records
For your domain at your DNS provider, create these records:
A Records
mail.yourdomain.com A YOUR_SERVER_IPyourdomain.com A YOUR_SERVER_IP
MX Records
yourdomain.com MX 10 mail.yourdomain.com
TXT Records
SPF Record:
yourdomain.com TXT "v=spf1 mx a:mail.yourdomain.com -all"
- DKIM Record (generated after Mailu setup):We'll generate this after starting Mailu
_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
PTR Record (Reverse DNS)
Contact your hosting provider to set up PTR record pointing to mail.yourdomain.com
Step 12: Start Mailu Services
# Navigate to Mailu directorycd ~/mailu# Start services in detached modedocker-compose up -d# Check statusdocker-compose ps# View logs (if needed)docker-compose logs -f
Step 13: Generate DKIM Key
# Generate DKIM keydocker-compose exec admin flask mailu dkim yourdomain.com# View the DKIM keycat /mailu/dkim/yourdomain.com.txt
Add the DKIM record to your DNS:
mail._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_HERE"
Part 4: SSL/TLS Configuration
Step 14: Configure Let's Encrypt
Mailu should automatically obtain SSL certificates. Verify:
# Check certificate directoryls -la /mailu/certs/# Check if certificates were obtaineddocker-compose logs front | grep -i cert
If certificates aren't being generated automatically, you can manually trigger:
# Renew certificatesdocker-compose exec front certbot renew
Step 15: Configure TLS Security
Create TLS configuration override:
# Create nginx TLS configurationsudo mkdir -p /mailu/overrides/nginx# Create TLS configuration filesudo vim /mailu/overrides/nginx/tls.conf
Add strong TLS configuration:
ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;ssl_prefer_server_ciphers off;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;add_header Strict-Transport-Security "max-age=63072000" always;
Part 5: Initial Configuration and Testing
Step 16: Access Admin Interface
Open browser to:
https://mail.yourdomain.com/adminLogin with:
[email protected]and your admin passwordChange the default admin password immediately
Step 17: Create Your First User
In Admin interface, navigate to "Users"
Click "Add user"
Fill in details:
Local part:
sugan(or your preferred username)Domain:
yourdomain.comPassword: Strong password
Quota: Set as needed (e.g., 5GB)
Click "Submit"
Step 18: Configure Email Client
For Thunderbird/Desktop Clients:
Incoming:
Server:
mail.yourdomain.comPort: 993 (IMAP SSL)
Authentication: Normal password
SSL/TLS: Yes
Outgoing:
Server:
mail.yourdomain.comPort: 587 (STARTTLS)
Authentication: Normal password
SSL/TLS: STARTTLS
For Mobile Devices:
Use the same settings as above. Most clients will auto-discover settings with proper DNS records.
Step 19: Test Email Functionality
# Test SMTP connectionsudo apt install -y telnettelnet mail.yourdomain.com 25EHLO yourdomain.comQUIT# Test IMAP connectionopenssl s_client -connect mail.yourdomain.com:993 -crlf# Send test email using swakssudo apt install -y swaks--server mail.yourdomain.com \--auth LOGIN \--auth-user [email protected] \--auth-password 'YOUR_PASSWORD' \-tls
Part 6: Advanced Configuration
Step 20: Configure Email Aliases
In Admin interface, go to "Aliases"
Click "Add alias"
Configure:
Source:
[email protected]Destination:
[email protected]Optional comment: "Contact form alias"
Step 21: Set Up Catch-All Address
Go to "Aliases"
Add alias:
Source:
@yourdomain.comDestination:
[email protected]
This catches all emails sent to non-existent addresses
Step 22: Configure Auto-Reply/Vacation
In Admin interface, go to "Users"
Click on your user
Scroll to "Auto-reply"
Enable and configure:
Subject: "Out of office"
Body: Your vacation message
Start/End dates (optional)
Step 23: Configure Spam Filtering
Edit .env file to enable spam filtering:
# Enable spam filteringWEBMAIL=roundcubeANTISPAM=rspamd
Update and restart:
docker-compose downdocker-compose up -d
Configure Rspamd via Admin interface under "Antispam" settings.
Step 24: Set Up Webmail
Access webmail at:
https://mail.yourdomain.com/webmailLogin with your email credentials
Configure Roundcube preferences:
Identity settings
Signature
Folder preferences
Contact management
Part 7: Security Hardening
Step 25: Configure Fail2Ban
# Install Fail2Bansudo apt install -y fail2ban# Create Mailu jail configurationsudo vim /etc/fail2ban/jail.d/mailu.conf
Add configuration:
[mailu]enabled = trueport = 80,443,25,465,587,993,995filter = mailulogpath = /mailu/data/mail/fail2ban.logmaxretry = 3bantime = 3600
Create filter:
sudo vim /etc/fail2ban/filter.d/mailu.conf
Add:
[Definition]failregex = ^.* Authentication failed: <HOST>$ignoreregex =
Restart Fail2Ban:
sudo systemctl restart fail2bansudo systemctl enable fail2ban
Step 26: Configure Log Rotation
# Create log rotation for Mailusudo vim /etc/logrotate.d/mailu
Add:
/mailu/data/mail/*.log {dailymissingokrotate 14compressdelaycompressnotifemptycreate 640 root rootsharedscriptspostrotatedocker restart $(docker ps -q --filter name=mailu)endscript}
Step 27: Set Up Monitoring
# Install monitoring toolssudo apt install -y prometheus-node-exporter# Configure Docker monitoringsudo vim /etc/docker/daemon.json
Add:
{"metrics-addr": "127.0.0.1:9323","experimental": true}
Step 28: Regular Backup Strategy
Create backup script:
vim ~/backup-mailu.shAdd:
#!/bin/bashBACKUP_DIR="/backup/mailu"DATE=$(date +%Y%m%d_%H%M%S)# Create backup directorymkdir -p $BACKUP_DIR/$DATE# Stop Mailu servicescd ~/mailudocker-compose down# Backup datatar -czf $BACKUP_DIR/$DATE/mailu_data.tar.gz /mailu# Backup configurationcp docker-compose.yml $BACKUP_DIR/$DATE/cp .env $BACKUP_DIR/$DATE/# Start Mailu servicesdocker-compose up -d# Remove backups older than 30 daysfind $BACKUP_DIR -type d -mtime +30 -exec rm -rf {} \;echo "Backup completed: $BACKUP_DIR/$DATE"
Make executable and schedule:
chmod +x ~/backup-mailu.sh(crontab -l 2>/dev/null; echo "0 2 * * * /home/sugan/backup-mailu.sh") | crontab -
Part 8: Troubleshooting Common Issues
Issue 1: Emails Not Sending
# Check mail logsdocker-compose logs smtp# Test SMTP connectiontelnet mail.yourdomain.com 25# Check DNS recordsdig mx yourdomain.comdig txt yourdomain.com
Issue 2: Emails Marked as Spam
Verify all DNS records (SPF, DKIM, DMARC)
Check PTR record
Ensure TLS is working properly
Check blacklist status:
dig +short yourdomain.com.dnsbl.example
Issue 3: Cannot Receive External Emails
# Check if port 25 is opensudo nmap -p 25 yourdomain.com# Check Postfix logsdocker-compose logs smtp | grep -i "reject"# Verify MX recorddig mx yourdomain.com
Issue 4: Web Interface Not Loading
# Check nginx logsdocker-compose logs front# Check if services are runningdocker-compose ps# Check port bindingsudo netstat -tlnp | grep :443
Issue 5: SSL Certificate Issues
# Force certificate renewaldocker-compose exec front certbot renew --force-renewal# Check certificate validityopenssl s_client -connect mail.yourdomain.com:443 -servername mail.yourdomain.com 2>/dev/null | openssl x509 -noout -dates
Part 9: Performance Optimization
Step 29: Optimize Database
# Create MySQL optimization configurationsudo vim /mailu/overrides/mysql/my.cnf
Add:
[mysqld]innodb_buffer_pool_size = 256Minnodb_log_file_size = 64Mquery_cache_size = 32Mtmp_table_size = 32Mmax_heap_table_size = 32M
Step 30: Configure Redis Caching
Add to .env:
# Enable Redis cacheREDIS_ADDRESS=redis
Step 31: Tune Dovecot for Performance
Create override:
sudo vim /mailu/overrides/dovecot/dovecot.conf
Add optimization:
mail_cache_min_mail_count = 50mailbox_idle_check_interval = 30s
Part 10: Maintenance and Updates
Step 32: Regular Maintenance Tasks
Create maintenance script:
vim ~/maintain-mailu.shAdd:
#!/bin/bashecho "Starting Mailu maintenance..."# Update system packagessudo apt update && sudo apt upgrade -y# Clean Dockerdocker system prune -f# Update Mailu imagescd ~/mailudocker-compose pulldocker-compose up -d# Check for errorsdocker-compose logs --tail=50echo "Maintenance completed!"
Step 33: Update Mailu
# Backup first./backup-mailu.sh# Stop servicesdocker-compose down# Pull new imagesdocker-compose pull# Update configuration if needed# Compare your docker-compose.yml with latest version# Start servicesdocker-compose up -d
Step 34: Monitor Resources
# Install monitoringsudo apt install -y glances# Run glancesglances# Or use docker statsdocker stats
Part 11: Additional Features
Step 35: Set Up Calendar and Contacts (CalDAV/CardDAV)
Add to docker-compose.yml:
radicale:image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}radicale:${MAILU_VERSION:-1.11}restart: alwaysenv_file: .envvolumes:- "/mailu/radicale:/data"
Update .env:
# Enable RadicaleCALENDAR=radicale
Step 36: Configure Sieve Filters
Access webmail
Go to Settings → Filters
Create server-side filters using Sieve syntax
Example filter to move newsletter to folder:
require ["fileinto"];if header :contains "List-ID" "newsletter" {fileinto "Newsletters";}
Step 37: Set Up Email Forwarding
Create forward in Admin interface:
Go to "Aliases"
Add new alias with external address as destination
Example:
[email protected]→[email protected]
Step 38: Configure API Access
Enable API in .env:
# Enable Admin APIADMIN_API=true
Use API for automation:
# Get tokencurl -X POST https://mail.yourdomain.com/admin/token \-H "Content-Type: application/json" \-d '{"email":"[email protected]","password":"your-password"}'# Use token to manage userscurl -X GET https://mail.yourdomain.com/admin/api/user \-H "Authorization: Bearer YOUR_TOKEN"
Conclusion
Congratulations! You've successfully set up a complete, self-hosted email server using Mailu on Debian. As Sugan Siddhant Dodrai, you now have:
Complete Control: Over your email infrastructure
Privacy: Your data stays on your server
Professional Setup: With proper DNS, TLS, and security
Scalability: Can grow with your needs
Learning: Valuable hands-on experience
Final Checklist
All DNS records properly configured
SSL certificates working
Can send and receive emails
Webmail accessible
Admin interface secured
Backups scheduled
Monitoring in place
Security measures implemented
Ongoing Responsibilities
Weekly: Check logs and monitor performance
Monthly: Update system and Mailu
Quarterly: Review security settings
Bi-annually: Test disaster recovery
Resources for Further Learning
Mailu Documentation: https://mailu.io
Postfix Documentation: http://www.postfix.org/documentation.html
Dovecot Documentation: https://doc.dovecot.org
SSL/TLS Best Practices: https://ssl-config.mozilla.org
Remember, running your own email server is a responsibility. Stay vigilant about security, keep regular backups, and enjoy the freedom and privacy that comes with self-hosting your email infrastructure.
About the Author: Sugan Siddhant Dodrai is a technology enthusiast passionate about self-hosted solutions and digital privacy. This guide represents comprehensive knowledge gathered from years of experience in system administration and email server management.

