Deploying Courier MTA
Introduction
Courier MTA is a powerful, open-source mail server and mail user agent written in C++. It provides a complete email system with support for SMTP message submission, POP3 and IMAP protocols for mail retrieval, local mail delivery, mail filtering, and extensive authentication mechanisms. Courier MTA is lightweight yet feature-rich, making it ideal for organizations that need fine-grained control over their email infrastructure.
Whether you’re building a custom email solution, integrating email capabilities into your application, or hosting email for multiple domains, Courier MTA provides the flexibility and performance you need. Deploying Courier MTA on Klutch.sh gives you a scalable email infrastructure with persistent storage for mail data, easy configuration management through environment variables, and reliable mail routing.
This comprehensive guide walks you through deploying Courier MTA on Klutch.sh, configuring mail protocols, setting up persistent storage for mail data, managing user authentication, and implementing production-ready best practices for reliable email delivery.
Why Deploy Courier MTA on Klutch.sh?
- Automated Docker Detection: Klutch.sh automatically detects your Dockerfile in the repository root and builds your container image automatically
- Multi-Protocol Support: Run SMTP, POP3, IMAP, and other mail protocols simultaneously on a single deployment
- Persistent Storage: Ensure mail data, user accounts, and configurations survive container restarts and deployments
- Flexible Configuration: Manage all Courier settings through environment variables with secure secret storage
- Network Isolation: TCP and HTTP traffic support for secure mail protocol communication
- Production-Ready: Deploy with confidence using containerized mail infrastructure
- Scalable Architecture: Grow your email capacity by allocating additional compute resources
Prerequisites
Before you begin deploying Courier MTA on Klutch.sh, ensure you have:
- A Klutch.sh account with dashboard access
- A GitHub account for repository hosting
- Docker installed locally for testing (optional but recommended)
- Basic understanding of email protocols (SMTP, POP3, IMAP) and mail server concepts
- Familiarity with mail filtering and user authentication systems
- Knowledge of Docker containers and containerized applications
- Domain name(s) for your mail server (required for production mail delivery)
- DNS access to configure MX records pointing to your mail server
- Understanding of mail user accounts and authentication backends
Understanding Courier MTA Architecture
Technology Stack
Courier MTA is built on proven, high-performance technologies for reliable email delivery:
Core Platform:
- C++ for the main mail server components with excellent performance and low resource overhead
- Berkeley DB or MySQL/MariaDB for mail account and user authentication storage
- LDAP support for enterprise directory integration
- PostgreSQL compatibility for large-scale deployments
- Perl and shell scripting for mail filtering and routing customization
Key Components:
- SMTP Server: Receive incoming mail from other mail servers and local applications, with full RFC compliance
- POP3 Server: Allow users to retrieve mail using traditional POP3 protocol with mailbox locking
- IMAP Server: Provide modern IMAP protocol support for accessing mail with folder synchronization
- Local Delivery Agent: Store and manage mail messages in user mailboxes with automatic folder organization
- Mail Router: Intelligent mail routing with support for virtual domains and mail forwarding
- Authentication System: Support multiple authentication backends including system users, LDAP, and database-backed authentication
- Mail Filtering Engine: Implement Sieve filtering rules for automatic mail organization and processing
- Rate Limiting: Control mail delivery rates and prevent mail loops
- TLS/SSL Support: Encrypt mail traffic between clients and servers
Features:
- Support for multiple virtual mail domains on a single server
- User mailbox management with automatic folder creation
- Mail forwarding and aliasing capabilities
- Sieve mail filtering language for complex mail rules
- SASL authentication with multiple mechanisms (LOGIN, PLAIN, CRAM-MD5, DIGEST-MD5)
- TLS/SSL encryption for SMTP, POP3, and IMAP protocols
- Connection throttling and rate limiting to prevent abuse
- Mail routing flexibility with customizable delivery rules
- Quota management for limiting mailbox sizes
- Integration with external authentication sources via LDAP
Installation and Setup
Step 1: Create Your Project Directory
Start by creating a new directory for your Courier MTA deployment project and initialize a Git repository:
mkdir courier-mta-klutchcd courier-mta-klutchgit initThis directory will contain your Dockerfile, configuration files, and mail system initialization scripts.
Step 2: Create the Dockerfile
Create a Dockerfile in your project root directory. Klutch.sh will automatically detect this file and use it to build your container. Here’s a production-ready Dockerfile for Courier MTA:
FROM ubuntu:22.04
# Set environment variablesENV DEBIAN_FRONTEND=noninteractive
# Update system packages and install Courier MTARUN apt-get update && apt-get install -y \ courier-mta \ courier-pop \ courier-imap \ courier-authlib \ courier-authlib-userdb \ libnet-server-perl \ libmail-spf-perl \ libmail-dkim-perl \ libmail-dmarc-perl \ maildrop \ procmail \ openssl \ ca-certificates \ gettext \ tzdata \ && rm -rf /var/lib/apt/lists/*
# Create necessary directories for mail storage and dataRUN mkdir -p /var/spool/courier \ /var/lib/courier \ /var/log/courier \ /etc/courier/certs \ /home/mail \ && chown -R daemon:daemon /var/spool/courier \ && chown -R daemon:daemon /var/lib/courier \ && chown -R daemon:daemon /var/log/courier
# Expose mail protocol portsEXPOSE 25 110 143 465 587 993 995
# Create entrypoint scriptRUN echo '#!/bin/bash\n\set -e\n\echo "Starting Courier MTA..."\n\/etc/init.d/courier-mta start\n\/etc/init.d/courier-pop start\n\/etc/init.d/courier-imap start\n\echo "Courier MTA started successfully"\n\tail -f /var/log/courier/current\n\' > /entrypoint.sh && chmod +x /entrypoint.sh
# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:8000/health || exit 1
ENTRYPOINT ["/entrypoint.sh"]Key Features of This Dockerfile:
- Based on Ubuntu 22.04 LTS for stability and long-term support
- Installs Courier MTA core components and support libraries
- Includes POP3, IMAP, SMTP, and authentication modules
- Creates persistent directories for mail storage and configuration
- Exposes standard mail protocol ports (25 for SMTP, 110 for POP3, 143 for IMAP, 587 for submission, 465/993/995 for secure variants)
- Includes mail filtering (maildrop) and virus scanning integrations
- Sets up proper file permissions for the daemon user
Step 3: Create Mail System Configuration Script
Create a config-courier.sh script to initialize and configure Courier MTA at startup:
#!/bin/bash
# config-courier.sh - Initialize Courier MTA configuration
set -e
COURIER_CONFIG_DIR="${COURIER_CONFIG_DIR:-/etc/courier}"COURIER_MAIL_DIR="${COURIER_MAIL_DIR:-/var/spool/courier}"
echo "Configuring Courier MTA..."
# Set hostname for mail systemif [ -n "$COURIER_HOSTNAME" ]; then echo "$COURIER_HOSTNAME" > "${COURIER_CONFIG_DIR}/me"fi
# Configure SMTP settingscat > "${COURIER_CONFIG_DIR}/smtpd" <<EOFADDRESS=0.0.0.0PORT=25MAXDAEMONS=100MAXPERIP=20
# TLS configurationTLS_REQUIRED=0TLS_CERTFILE=${COURIER_CONFIG_DIR}/certs/server.crtTLS_KEYFILE=${COURIER_CONFIG_DIR}/certs/server.key
# Authentication requirementsSMTP_ACCEPT_EMAIL=1SMTP_ACCEPTMUTUALSTARTTLS=1EOF
# Configure local deliverycat > "${COURIER_CONFIG_DIR}/defaultdelivery" <<EOF./Maildir/EOF
# Create user mail directories if they don't existmkdir -p "${COURIER_MAIL_DIR}/Maildir"/{cur,new,tmp}chown -R daemon:daemon "${COURIER_MAIL_DIR}"
echo "Courier MTA configuration complete"Save this as config-courier.sh and add it to your Dockerfile:
# Add this to your Dockerfile before the ENTRYPOINTCOPY config-courier.sh /config-courier.shRUN chmod +x /config-courier.sh && /config-courier.shStep 4: Set Up User Authentication Database
Create an init-users.sh script for initializing mail user accounts:
#!/bin/bash
# init-users.sh - Initialize mail user accounts
set -e
COURIER_CONFIG_DIR="${COURIER_CONFIG_DIR:-/etc/courier}"
echo "Initializing Courier user authentication..."
# Create mail user accounts databaseif [ -z "$(getent passwd mailuser)" ]; then useradd -m -s /sbin/nologin mailuser 2>/dev/null || truefi
# Add mail users with userdb backend# Example: add a mail user with username 'user@example.com' and password 'secure_password'if [ -n "$COURIER_MAIL_USERS" ]; then IFS=',' read -ra USERS <<< "$COURIER_MAIL_USERS" for user in "${USERS[@]}"; do # Parse user format: username@domain:password USERNAME=$(echo "$user" | cut -d: -f1) PASSWORD=$(echo "$user" | cut -d: -f2)
if [ -n "$USERNAME" ] && [ -n "$PASSWORD" ]; then echo "Adding mail user: $USERNAME" echo "$PASSWORD" | userdb "$USERNAME" set systempw "$PASSWORD" fi donefi
echo "User authentication initialization complete"Step 5: Generate SSL/TLS Certificates
For production deployments with encrypted mail protocols, generate self-signed certificates. Create a gen-certs.sh script:
#!/bin/bash
# gen-certs.sh - Generate SSL/TLS certificates for Courier MTA
set -e
CERT_DIR="${CERT_DIR:-/etc/courier/certs}"CERT_FILE="${CERT_DIR}/server.crt"KEY_FILE="${CERT_DIR}/server.key"DOMAIN="${COURIER_HOSTNAME:-mail.example.com}"
mkdir -p "$CERT_DIR"
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then echo "Generating self-signed certificate for $DOMAIN..."
openssl req -x509 -newkey rsa:2048 -keyout "$KEY_FILE" -out "$CERT_FILE" \ -days 365 -nodes \ -subj "/C=US/ST=State/L=City/O=Organization/CN=$DOMAIN"
chmod 600 "$KEY_FILE" chmod 644 "$CERT_FILE"
echo "Certificates generated successfully"else echo "Certificates already exist, skipping generation"fiAdd to your Dockerfile:
# Add this to your DockerfileCOPY gen-certs.sh /gen-certs.shRUN chmod +x /gen-certs.sh && /gen-certs.shStep 6: Test Locally with Docker (Optional)
Before deploying to Klutch.sh, you can test your Courier MTA setup locally:
# Build the Docker imagedocker build -t my-courier-mta .
# Run the container with environment variablesdocker run -d \ --name courier-mta \ -p 25:25 \ -p 110:110 \ -p 143:143 \ -p 587:587 \ -p 993:993 \ -p 995:995 \ -e COURIER_HOSTNAME=mail.example.com \ -v courier-mail:/var/spool/courier \ -v courier-config:/etc/courier \ my-courier-mta
# Check logsdocker logs -f courier-mta
# Test SMTP connectiontelnet localhost 25
# Stop the containerdocker stop courier-mtadocker rm courier-mtadocker volume rm courier-mail courier-configStep 7: Prepare Your Repository for Deployment
Commit your configuration files to your GitHub repository:
git add Dockerfile config-courier.sh init-users.sh gen-certs.shgit commit -m "Add Courier MTA Docker configuration and initialization scripts"git remote add origin https://github.com/yourusername/courier-mta-klutch.gitgit branch -M maingit push -u origin mainEnvironment Variables Configuration
Courier MTA requires several environment variables for proper configuration. These should be configured in the Klutch.sh dashboard under your app’s environment variables section.
Essential Environment Variables
Mail Server Identity:
COURIER_HOSTNAME=mail.example.comCOURIER_DOMAINNAME=example.comSMTP Configuration:
COURIER_SMTP_PORT=25COURIER_SMTP_ADDRESS=0.0.0.0COURIER_SUBMISSION_PORT=587COURIER_SUBMISSIONS_PORT=465COURIER_SMTP_MAXDAEMONS=100POP3 Configuration:
COURIER_POP3_PORT=110COURIER_POP3S_PORT=995COURIER_POP3_ADDRESS=0.0.0.0COURIER_POP3_MAXDAEMONS=100IMAP Configuration:
COURIER_IMAP_PORT=143COURIER_IMAPS_PORT=993COURIER_IMAP_ADDRESS=0.0.0.0COURIER_IMAP_MAXDAEMONS=100Mail Storage:
COURIER_MAIL_DIR=/var/spool/courierCOURIER_CONFIG_DIR=/etc/courierCOURIER_LOG_DIR=/var/log/courierTLS/SSL Configuration:
COURIER_TLS_REQUIRED=0COURIER_TLS_CERTFILE=/etc/courier/certs/server.crtCOURIER_TLS_KEYFILE=/etc/courier/certs/server.keyAuthentication:
COURIER_AUTH_METHOD=userdbCOURIER_MAIL_USERS=user1@example.com:password1,user2@example.com:password2Optional Environment Variables
Mail Filtering and Processing:
COURIER_ENABLE_SIEVE=1COURIER_SIEVE_RULES_DIR=/etc/courier/sieveCOURIER_ENABLE_MAILDROP=1Performance Tuning:
COURIER_MAX_CONNECTIONS=500COURIER_TIMEOUT=900COURIER_RATE_LIMIT=50Logging:
COURIER_LOG_LEVEL=5COURIER_DEBUG=0Important Security Notes:
- Always use strong, unique passwords for mail user accounts
- Never commit plaintext credentials to your Git repository
- Use Klutch.sh’s environment variable management for all sensitive data
- Enable TLS for all remote connections in production
- Restrict mail relay to authenticated users only
- Implement rate limiting to prevent abuse and spam
Persistent Storage Configuration
Courier MTA manages user mail data and system configuration that must persist across container restarts and deployments. You need to configure persistent volumes for critical directories.
Critical Directories for Persistence
- Mail Spool (
/var/spool/courier) - User mailboxes and stored messages - Configuration (
/etc/courier) - Mail server configuration and routing rules - Logs (
/var/log/courier) - Mail server logs for debugging and monitoring
Recommended Volume Configuration
When creating your Courier MTA app on Klutch.sh, attach persistent volumes with the following mount paths:
Mail Data Volume:
- Mount Path:
/var/spool/courier - Size: 10GB minimum (adjust based on expected mail volume)
- Purpose: Store all user mailboxes and mail messages
Configuration Volume:
- Mount Path:
/etc/courier - Size: 2GB (for configuration files and certificates)
- Purpose: Persist mail server configuration and TLS certificates
Logs Volume:
- Mount Path:
/var/log/courier - Size: 5GB (adjust based on mail server activity)
- Purpose: Store mail server logs for debugging and monitoring
Volume Size Recommendations
- Small deployment (< 100 users): 10GB mail, 2GB config, 5GB logs
- Medium deployment (100-1000 users): 50GB mail, 2GB config, 10GB logs
- Large deployment (> 1000 users): 100GB+ mail, 5GB config, 20GB+ logs
Storage requirements depend on average message size and mail retention policies. Plan accordingly for your expected mail volume.
Deploying to Klutch.sh
Now that your Courier MTA project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh with persistent storage and proper configuration.
Deployment Steps
-
Log in to Klutch.sh
Navigate to klutch.sh/app and sign in to your account.
-
Create a New Project
From your dashboard, create a new project. Give it a meaningful name like “Courier Mail Server” to organize your deployments.
-
Create a New App
Within your project, create a new app for your mail server deployment.
-
Select Your Repository
- Choose GitHub as your Git source
- Select the repository containing your Courier MTA Dockerfile
- Choose the branch you want to deploy (typically
mainormaster)
-
Configure Traffic Type
Since Courier MTA uses multiple mail protocols via TCP, select TCP as your traffic type. This allows simultaneous access to SMTP, POP3, and IMAP ports from a single deployment.
-
Configure Ports
Courier MTA will be accessible on TCP port 8000 from outside the cluster. You can configure internal port mapping for your mail protocols:
- Internal SMTP Port: 25 (standard SMTP)
- Internal Submission Port: 587 (mail submission)
- Internal Secure SMTP Port: 465 (SMTPS)
- Internal POP3 Port: 110 (standard POP3)
- Internal Secure POP3 Port: 995 (POP3S)
- Internal IMAP Port: 143 (standard IMAP)
- Internal Secure IMAP Port: 993 (IMAPS)
Configure your mail clients to connect to
example-app.klutch.shon port 8000 using the appropriate mail protocol. -
Set Environment Variables
In the environment variables section, add all the necessary Courier MTA configuration variables from the “Environment Variables Configuration” section above. Make sure to:
- Set
COURIER_HOSTNAMEto your mail server’s fully qualified domain name - Configure authentication credentials securely
- Mark sensitive variables as secrets
- Set
-
Attach Persistent Volumes
This is critical for preserving mail data and configuration across deployments:
Mail Data Volume:
- Mount Path:
/var/spool/courier - Size: 10GB (or larger based on your needs)
Configuration Volume:
- Mount Path:
/etc/courier - Size: 2GB
Logs Volume:
- Mount Path:
/var/log/courier - Size: 5GB (or larger for high-volume servers)
- Mount Path:
-
Configure Compute Resources
Select appropriate compute resources based on your mail server load:
- Minimum: 1 CPU, 2GB RAM (for small mail servers < 50 users)
- Recommended: 2 CPU, 4GB RAM (for production servers with moderate mail volume)
- High-Scale: 4+ CPU, 8GB+ RAM (for large mail servers > 500 users)
-
Deploy Your Application
Click “Create” to start the deployment. Klutch.sh will:
- Automatically detect your Dockerfile in the repository root
- Build the Docker image with your configuration
- Attach the persistent volumes you specified
- Deploy the container with your environment variables
- Assign a hostname for accessing your mail server
-
Configure DNS Records
After deployment, configure your DNS records to route mail to your Courier MTA instance:
Add MX Record:
example.com MX 10 example-app.klutch.sh.Add A/AAAA Records (if needed):
example-app A xxx.xxx.xxx.xxxReplace
example.comwith your domain andexample-app.klutch.shwith your assigned app hostname. Mail servers on the internet will use the MX record to route mail to your Courier MTA instance.
Getting Started with Courier MTA
After deployment, follow these steps to configure mail accounts and test your mail server.
Initial Setup
-
Access Your Server
Your Courier MTA instance is now running at
example-app.klutch.shon port 8000. Mail clients can connect using the appropriate protocol (SMTP, POP3, IMAP). -
Create Mail User Accounts
Use the environment variables to define mail user accounts. Update your
COURIER_MAIL_USERSvariable with comma-separated entries in the formatusername@domain.com:password. -
Configure Mail Clients
Thunderbird Configuration Example:
- Server: example-app.klutch.sh
- Port: 8000
- Protocol: IMAP or POP3
- Username: user@example.com
- Password: your-password
- Security: STARTTLS or IMAPS/POP3S (depending on your TLS setup)
Outlook Configuration Example:
- Server: example-app.klutch.sh:8000
- Protocol: IMAP or POP3
- Username: user@example.com
- Password: your-password
- Encryption: TLS/SSL
-
Test Mail Sending and Receiving
- Use your mail client to send a test email
- Check that emails are delivered to user mailboxes
- Verify that incoming mail from external servers arrives correctly
Configuring Mail Forwarding
Set up mail forwarding rules using Courier’s .courier file in user mailbox directories:
# In /var/spool/courier/user/.courier# Forward all mail to another addressforward: another-user@example.com
# Local delivery plus forwarding!.maildir:forward: another-user@example.comSetting Up Mail Filtering with Sieve
Courier supports Sieve mail filtering. Create filter rules in the .sieve file:
# Example: Auto-organize mail into foldersrequire ["fileinto"];
if header :contains "subject" "project" { fileinto "Projects"; stop;}
if header :contains "from" "@company.com" { fileinto "Company"; stop;}
# Discard known spamif header :contains "x-spam-status" "YES" { discard; stop;}Integration with External Applications
Sending Mail via SMTP in PHP:
<?php$to = "user@example.com";$subject = "Test Email";$message = "This is a test email from Courier MTA";$headers = "From: sender@example.com\r\n";
// Use mail() function which connects to SMTP// or use PHPMailer for more controlrequire 'PHPMailer/PHPMailer.php';require 'PHPMailer/Exception.php';
$mail = new PHPMailer\PHPMailer\PHPMailer();$mail->isSMTP();$mail->Host = 'example-app.klutch.sh';$mail->Port = 8000;$mail->setFrom('sender@example.com');$mail->addAddress('user@example.com');$mail->Subject = 'Test Email';$mail->Body = 'This is a test email';
if (!$mail->send()) { echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";}?>Sending Mail via SMTP in Node.js:
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({ host: 'example-app.klutch.sh', port: 8000, secure: false, // Use TLS if enabled auth: { user: 'sender@example.com', pass: 'password' }});
transporter.sendMail({ from: 'sender@example.com', to: 'user@example.com', subject: 'Test Email', text: 'This is a test email from Courier MTA', html: '<b>This is a test email from Courier MTA</b>'}, (error, info) => { if (error) { console.log('Error:', error); } else { console.log('Email sent:', info.response); }});Receiving Mail via IMAP in Python:
import imaplibimport email
# Connect to IMAP serverimap = imaplib.IMAP4(host='example-app.klutch.sh', port=8000)imap.login('user@example.com', 'password')
# Select INBOXimap.select('INBOX')
# Search for emailsstatus, messages = imap.search(None, 'ALL')
# Process emailsfor msg_id in messages[0].split(): status, msg_data = imap.fetch(msg_id, '(RFC822)') email_message = email.message_from_string(msg_data[0][1].decode()) print(f"From: {email_message['From']}") print(f"Subject: {email_message['Subject']}")
imap.close()imap.logout()Production Best Practices
Security Recommendations
Mail Protocol Security:
- Enable TLS/SSL for all remote connections (POP3S, IMAPS, SMTPS)
- Use strong encryption certificates (self-signed is acceptable for internal use)
- Disable unencrypted protocols (SMTP, POP3, IMAP) for external access
- Require authentication for SMTP submission to prevent open relays
User Account Security:
- Use strong, unique passwords for all mail accounts
- Implement password complexity requirements
- Regularly audit mail user accounts and remove inactive accounts
- Enable account lockout after failed login attempts
- Store credentials securely using environment variables
Network Security:
- Restrict mail server access to trusted networks only
- Implement firewall rules to limit SMTP relay to authenticated users
- Monitor mail server logs for suspicious activity
- Enable connection rate limiting to prevent abuse
- Consider implementing SPF, DKIM, and DMARC records for domain authentication
Data Protection:
- Enable mail logging for audit trails
- Regularly backup mail data and configuration
- Implement mail quota limits to prevent disk space exhaustion
- Use encryption for sensitive mail data at rest
Performance Optimization
Connection Management:
- Configure appropriate connection pool sizes based on expected users
- Adjust maximum concurrent connections (MAXDAEMONS setting)
- Implement connection timeouts to clean up idle connections
- Monitor connection resource usage
Mail Storage Optimization:
- Use efficient mailbox format (Maildir is recommended for scalability)
- Implement mail quota management to prevent runaway storage
- Archive old mail to reduce active storage requirements
- Monitor mailbox sizes and warn users approaching quotas
Database Optimization:
- If using a database backend, optimize indexes on frequently queried fields
- Monitor database query performance
- Regular maintenance and cleanup of deleted mail records
- Consider separate database server for large deployments
Caching Strategies:
- Cache user authentication information when possible
- Implement DNS caching for mail routing decisions
- Use connection pooling for database connections
- Cache frequently accessed configuration
Monitoring and Maintenance
Health Monitoring:
- Monitor mail delivery success and failure rates
- Track SMTP relay rejections and bounce messages
- Monitor server resource usage (CPU, memory, disk)
- Alert on certificate expiration (typically 30 days before)
- Monitor mail queue depth and delivery latency
Regular Maintenance Tasks:
- Review mail server logs weekly for errors and warnings
- Perform monthly backups of mail data and configuration
- Update Courier MTA to latest stable version for security patches
- Audit mail user accounts and remove inactive users
- Verify TLS certificate validity and plan for renewals
- Clean up mail queue for delivery failures
Backup Strategy:
# Example backup script for mail data#!/bin/bashBACKUP_DIR="/backup/courier-mta"TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Backup mail spooltar -czf "${BACKUP_DIR}/mail-spool-${TIMESTAMP}.tar.gz" /var/spool/courier
# Backup configurationtar -czf "${BACKUP_DIR}/config-${TIMESTAMP}.tar.gz" /etc/courier
# Keep backups for 30 daysfind "${BACKUP_DIR}" -name "*.tar.gz" -mtime +30 -deleteScaling Considerations
Single Instance Scaling:
- Vertical scaling (more CPU/RAM) suitable for most deployments
- Supports hundreds of concurrent users on single instance
- Monitor resource usage and increase allocation as needed
Multi-Instance Scaling:
- For very large deployments (1000+ users), consider multiple instances
- Requires load balancer in front of mail servers
- Implement shared mail storage backend (NFS or distributed filesystem)
- Synchronize configuration across instances
Database Scaling:
- For production deployments, use external database for user authentication
- Implement database replication for high availability
- Monitor database performance and optimize queries
- Plan for database backup and recovery
Troubleshooting
Common Issues and Solutions
Issue: Clients Cannot Connect to Mail Server
- Check: Verify app is running and healthy in Klutch.sh dashboard
- Check: Confirm TCP port 8000 is accessible from client locations
- Check: Review mail server logs for connection errors
- Check: Verify DNS records are correctly configured
- Solution: Check firewall rules blocking mail protocol ports
- Solution: Verify environment variables are set correctly
- Solution: Test connection using telnet:
telnet example-app.klutch.sh 8000
Issue: Cannot Authenticate to Mail Server
- Check: Verify user account exists and password is correct
- Check: Confirm COURIER_MAIL_USERS environment variable is set properly
- Check: Check mail server logs for authentication failures
- Check: Verify authentication backend is configured correctly
- Solution: Restart mail server after updating user accounts
- Solution: Test authentication using telnet and SMTP AUTH command
- Solution: Verify user database is accessible and has correct permissions
Issue: Mail Not Being Delivered
- Check: Verify SMTP is accepting mail (check for relay restrictions)
- Check: Confirm mail user accounts exist on the server
- Check: Review mail queue status and delivery logs
- Check: Verify mailbox directory permissions (should be owned by daemon:daemon)
- Solution: Check DNS MX record configuration
- Solution: Verify mail storage has sufficient disk space
- Solution: Test mail delivery using telnet or mail client
Issue: High Memory or CPU Usage
- Cause: Too many concurrent connections or large mailboxes
- Solution: Increase container resource allocation
- Solution: Implement connection rate limiting
- Solution: Archive old mail to reduce mailbox sizes
- Solution: Monitor and optimize mail filtering rules
Issue: SSL/TLS Certificate Errors
- Cause: Self-signed certificate or certificate expiration
- Check: Verify certificate files exist in /etc/courier/certs
- Check: Check certificate expiration date
- Solution: Regenerate certificate using gen-certs.sh
- Solution: For production, use proper certificate from Certificate Authority
Issue: Persistent Data Lost After Redeployment
- Cause: Persistent volumes not properly attached
- Check: Verify volume mount paths match exactly:
/var/spool/courier,/etc/courier,/var/log/courier - Check: Confirm volumes have sufficient available space
- Solution: Re-attach volumes with correct mount paths before redeploying
- Solution: Ensure volumes are not accidentally deleted during deployment
Issue: Mail Relay Being Blocked
- Check: Verify authentication is enabled for submission port (587)
- Check: Confirm SMTP_ACCEPT_EMAIL setting allows relay for authenticated users
- Check: Review rate limiting settings (COURIER_RATE_LIMIT)
- Solution: Enable TLS and require authentication for mail submission
- Solution: Configure SPF records to prevent spoofing
- Solution: Implement DKIM signing for better mail deliverability
Getting Help
If you encounter issues not covered here:
- Review Courier MTA official documentation
- Check the Courier MTA mailing list archives
- Consult the Courier FAQ
- Review mail server logs for detailed error messages
- Contact Klutch.sh support through the dashboard
Advanced Configuration
Virtual Domain Configuration
Support multiple mail domains on a single Courier MTA instance:
# domain usernameexample.com examplemail.org mailcustomer.io customerConfigure routing for virtual domains in your configuration script.
LDAP Authentication Integration
Use LDAP for centralized user authentication:
# Set in environment variablesCOURIER_AUTH_METHOD=ldapCOURIER_LDAP_HOST=ldap.example.comCOURIER_LDAP_PORT=389COURIER_LDAP_BASEDN=ou=people,dc=example,dc=comCOURIER_LDAP_FILTER=(uid=%username)Database-Backed Authentication
Use MySQL/PostgreSQL for flexible user management:
# Set in environment variablesCOURIER_AUTH_METHOD=sqlCOURIER_SQL_DATABASE=couriermailCOURIER_SQL_USER=courier_appCOURIER_SQL_PASSWORD=secure_passwordCOURIER_SQL_HOST=db.example.comCustom Mail Routing Rules
Create advanced mail routing using maildrop:
# Route mail based on headersif (/^To:.*special@/){ to "special"}
# Archive old mailif ($DATE < "2024-01-01"){ to ".Archive"}
# Route to folders based on sendersif (from "important-client@"){ to ".Clients.Important"}Rate Limiting and Abuse Prevention
Configure rate limiting to prevent spam and abuse:
COURIER_RATE_LIMIT=50 # Messages per minuteCOURIER_CONNECTIONS_PER_IP=5 # Max connections per IPCOURIER_MAX_MESSAGES_PER_CONNECTION=100COURIER_CONNECTION_TIMEOUT=600Additional Resources
- Courier MTA Official Website
- Courier Local Delivery Configuration
- Maildir Format Documentation
- IMAP/POP3 Configuration Guide
- Sieve Mail Filtering Language
- Klutch.sh Volumes Guide
- Klutch.sh Deployments Guide
- Klutch.sh Custom Domains Guide
- Klutch.sh Quick Start Guide
Conclusion
Deploying Courier MTA on Klutch.sh provides a powerful, flexible email infrastructure for your applications and users. With automated Docker detection, multi-protocol support for SMTP, POP3, and IMAP, persistent storage for mail data, and secure configuration management, Klutch.sh simplifies mail server deployment while maintaining production-grade reliability.
By following this comprehensive guide, you’ve learned how to:
- Create a production-ready Dockerfile for Courier MTA with all essential mail protocols
- Configure SMTP, POP3, IMAP, and secure variants of each protocol
- Set up persistent volumes for mail data, configuration, and logs
- Manage user authentication and mail account creation
- Implement TLS/SSL encryption for secure mail protocols
- Generate and manage SSL/TLS certificates
- Integrate Courier MTA with external applications via SMTP
- Monitor and optimize mail server performance
- Implement best practices for security and reliability
- Troubleshoot common mail server issues
Your Courier MTA mail server is now ready to handle email delivery for your applications and users. As your mail volume grows, you can easily scale your Klutch.sh deployment by allocating additional compute resources and expanding persistent storage for mail data.