MailCow Self-hosted email server with webmail, spam filtering & antivirus. Complete Mailcow solution with IMAP/POP3, calendar, contacts & automatic SSL. 1.0.0 - ami-0ad4b852fd26dc0df Mailcow Email Server - AWS Marketplace AMI Complete, production-ready email server solution powered by Mailcow, optimized for AWS deployment. Overview This AMI provides a fully-featured email server including: Postfix - Mail Transfer Agent (MTA) Dovecot - IMAP/POP3 server SOGo - Webmail, calendar, and contacts Rspamd - Spam filtering ClamAV - Antivirus scanning Let's Encrypt - Automatic SSL certificates Fail2ban - Intrusion prevention (host-level for SSH) Requirements Instance Requirements Component Minimum Recommended Instance Type t3.medium t3.large or better vCPUs 2 4+ RAM 4 GB 8 GB+ Root Volume 20 GB 30 GB Data Volume (EBS) 50 GB 100 GB+ Network Requirements Port Protocol Purpose 22 TCP SSH 25 TCP SMTP (inbound) 80 TCP HTTP (Let's Encrypt) 110 TCP POP3 143 TCP IMAP 443 TCP HTTPS 465 TCP SMTPS 587 TCP Submission 993 TCP IMAPS 995 TCP POP3S 4190 TCP ManageSieve DNS Requirements Before configuration, set up these DNS records: # A Record (required) mail.example.com. IN A YOUR_PUBLIC_IP # MX Record (required) example.com. IN MX 10 mail.example.com. # SPF Record (required) example.com. IN TXT "v=spf1 mx a -all" # DMARC Record (recommended) _dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:postmaster@example.com" # DKIM Record (configure after installation via admin panel) ⚠️ IMPORTANT: AWS Port 25 Restriction AWS blocks outbound SMTP (port 25) by default. Your server cannot send emails until you: Request port 25 removal from AWS: https://aws.amazon.com/forms/ec2-email-limit-rdns-request Or configure Amazon SES as relay See /opt/mailcow/scripts/AWS-PORT25-GUIDE.md for detailed instructions. Quick Start Option 1: Interactive Configuration (SSH) Launch the AMI with: Instance type: t3.medium or larger Attach an EBS volume (50GB+) for mail data Configure Security Group with required ports SSH into the instance: ssh -i your-key.pem ubuntu@your-instance-ip Run the configuration script: sudo /opt/mailcow/scripts/configure-mailcow.sh Follow the prompts to configure: Mail hostname (e.g., mail.example.com) Admin email address Timezone SSL/TLS settings Access the admin panel: URL: https://your-hostname Username: admin Password: moohoo (change immediately!) Option 2: Automated Configuration (User-Data) Launch the instance with this JSON user-data: { "hostname": "mail.example.com", "admin_email": "admin@example.com", "timezone": "UTC", "skip_letsencrypt": "n" } CloudFormation Example: AWSTemplateFormatVersion: '2010-09-09' Description: Mailcow Email Server Parameters: MailHostname: Type: String Description: Mail server hostname (e.g., mail.example.com) AdminEmail: Type: String Description: Admin email for notifications and certificates InstanceType: Type: String Default: t3.medium KeyName: Type: AWS::EC2::KeyPair::KeyName Resources: MailcowInstance: Type: AWS::EC2::Instance Properties: ImageId: !Ref MailcowAMI # Replace with actual AMI ID InstanceType: !Ref InstanceType KeyName: !Ref KeyName SecurityGroupIds: - !Ref MailcowSecurityGroup UserData: Fn::Base64: !Sub | { "hostname": "${MailHostname}", "admin_email": "${AdminEmail}", "timezone": "UTC" } BlockDeviceMappings: - DeviceName: /dev/sdf Ebs: VolumeSize: 100 VolumeType: gp3 DeleteOnTermination: false MailcowSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Mailcow Email Server SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 25 ToPort: 25 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 110 ToPort: 110 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 143 ToPort: 143 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 465 ToPort: 465 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 587 ToPort: 587 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 993 ToPort: 993 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 995 ToPort: 995 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 4190 ToPort: 4190 CidrIp: 0.0.0.0/0 Management Commands Use the mailcow-cli utility for common operations: # Check service status mailcow-cli status # View logs mailcow-cli logs mailcow-cli logs postfix-mailcow # Specific service # Start/Stop/Restart sudo mailcow-cli start sudo mailcow-cli stop sudo mailcow-cli restart # Show configuration mailcow-cli info # Show required DNS records mailcow-cli dns # Mail queue management mailcow-cli queue list sudo mailcow-cli queue flush sudo mailcow-cli queue delete ALL # Backup data sudo mailcow-cli backup # Update Mailcow sudo mailcow-cli update # Open shell in container mailcow-cli shell postfix-mailcow Configuration Access Admin Panel URL: https://your-hostname Username: admin Default Password: moohoo Change the admin password immediately after first login! Create Domains and Mailboxes Log into admin panel Go to Email → Configuration Add your domain Create mailboxes under the domain Configure DKIM Go to Configuration → Configuration & Details Find ARC/DKIM keys section Copy the DKIM record shown Add to your DNS Configure Email Clients IMAP Settings: Server: mail.example.com Port: 993 (SSL/TLS) or 143 (STARTTLS) Username: Full email address Password: Mailbox password SMTP Settings: Server: mail.example.com Port: 587 (STARTTLS) or 465 (SSL/TLS) Username: Full email address Password: Mailbox password Data Storage EBS Volume Layout When using a separate EBS volume (recommended): Path Contents /mnt/mailcow-data/vmail Email storage /mnt/mailcow-data/mysql Database /mnt/mailcow-data/redis Cache /mnt/mailcow-data/rspamd Spam filter data /mnt/mailcow-data/crypt Encryption keys /mnt/mailcow-data/backup Backup files Backup Strategy Automated Backups: # Create backup sudo mailcow-cli backup # Backups stored in: /mnt/mailcow-data/backup/ Manual Backup: # Stop services for consistent backup cd /opt/mailcow/mailcow-dockerized sudo docker compose stop # Backup data volume sudo tar -czf mailcow-backup-$(date +%Y%m%d).tar.gz /mnt/mailcow-data # Restart services sudo docker compose up -d Restore from Backup: sudo mailcow-cli restore /path/to/backup.tar.gz Monitoring Service Health # Overall status mailcow-cli status # Docker container status docker compose -f /opt/mailcow/mailcow-dockerized/docker-compose.yml ps Logs # All services mailcow-cli logs # Specific services mailcow-cli logs postfix-mailcow # SMTP mailcow-cli logs dovecot-mailcow # IMAP/POP3 mailcow-cli logs rspamd-mailcow # Spam filter mailcow-cli logs nginx-mailcow # Web Mail Queue # View queue mailcow-cli queue list # Flush stuck messages sudo mailcow-cli queue flush Troubleshooting Cannot Send Email (Port 25 Blocked) This is the #1 issue on AWS. See /opt/mailcow/scripts/AWS-PORT25-GUIDE.md . # Test outbound port 25 telnet gmail-smtp-in.l.google.com 25 # If it times out, port 25 is blocked SSL Certificate Issues # Check certificate status docker compose exec acme-mailcow /root/acme.sh --list # Force certificate renewal docker compose exec acme-mailcow /root/acme.sh --renew -d mail.example.com --force Cannot Receive Email Check DNS MX record: dig MX example.com Check port 25 is open inbound in Security Group Check Postfix logs: mailcow-cli logs postfix-mailcow High Memory Usage Mailcow runs many services. If memory is constrained: # Edit mailcow.conf nano /opt/mailcow/mailcow-dockerized/mailcow.conf # Disable optional services SKIP_CLAMD=y # Disable antivirus SKIP_SOLR=y # Disable full-text search # Restart docker compose up -d Container Not Starting # Check container logs docker logs mailcowdockerized-postfix-mailcow-1 # Check disk space df -h # Check Docker status systemctl status docker Building the AMI Prerequisites Launch a clean Ubuntu 24.04 instance (t3.medium) Attach a 30GB root volume Build Steps # 1. Run setup script sudo /opt/mailcow/scripts/setup-mailcow.sh # 2. Install CLI and scripts sudo cp mailcow-cli /usr/local/bin/ sudo chmod +x /usr/local/bin/mailcow-cli sudo cp configure-mailcow.sh first-boot.sh /opt/mailcow/scripts/ sudo chmod +x /opt/mailcow/scripts/*.sh sudo cp mailcow-firstboot.service /etc/systemd/system/ sudo systemctl enable mailcow-firstboot.service sudo cp AWS-PORT25-GUIDE.md /opt/mailcow/scripts/ # 3. Test configuration (optional) sudo /opt/mailcow/scripts/configure-mailcow.sh # 4. Cleanup for AMI sudo /opt/mailcow/scripts/cleanup-for-ami.sh # 5. Create AMI from AWS Console Security Considerations Change admin password immediately after configuration Use Elastic IP for consistent email reputation Request reverse DNS (PTR) from AWS Keep Mailcow updated with mailcow-cli update Monitor logs for suspicious activity Enable 2FA in Mailcow admin panel Backup regularly to protect your data Support Logs Location First boot: /var/log/mailcow/first-boot.log Mailcow: mailcow-cli logs System: /var/log/syslog Configuration Files Mailcow config: /opt/mailcow/mailcow-dockerized/mailcow.conf Saved info: /opt/mailcow/config-info.txt Credentials: /opt/mailcow/.credentials (root only) Resources Mailcow Documentation: https://docs.mailcow.email/ Mailcow GitHub: https://github.com/mailcow/mailcow-dockerized AWS Port 25 Form: https://aws.amazon.com/forms/ec2-email-limit-rdns-request Version Information Mailcow: Latest from GitHub (pulled during configuration) Ubuntu: 24.04 LTS Docker: Latest stable AMI Version: 1.0.0 License Mailcow is licensed under the GNU General Public License v3.0. This AMI packaging is provided for AWS Marketplace deployment.