9.4 KiB
Docker Postfix SMTP Relay
A lightweight Postfix SMTP relay container supporting multiple email service providers including Maileroo, Mailtrap, SendGrid, and any generic SMTP server.
The image uses Alpine 3.24 (musl libc) and is published as k2patel/postfix:latest.
Builds run on Gitea for pushes to main, monthly, or by manual dispatch.
Features
- 🚀 Multi-provider support (Maileroo, Mailtrap, SendGrid, Gmail, Office365, any SMTP)
- 🔒 TLS/SSL encryption
- 🌐 Auto-detects /16 subnet for relay
- 📝 All logs to stderr (
docker logs) - 🏥 Built-in health checks
- 🔧 Simple Makefile-based operations
Quick Start
1. Clone and Configure
git clone https://git.k2patel.in/k2patel/docker-postfix.git
cd docker-postfix
cp env.sample .env
nano .env # Edit with your SMTP provider details
2. Build and Start
cd test
make build
make up
3. Test
cd test
make test TO=your@email.com
Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
SMTP_SERVER |
Yes | - | SMTP server hostname |
SMTP_PORT |
Yes | 587 | SMTP server port |
SMTP_USERNAME |
Yes | - | SMTP username |
SMTP_PASSWORD |
Yes | - | SMTP password |
DOMAIN |
Yes | - | Domain for outgoing mail |
SERVER_HOSTNAME |
No | Auto | Server FQDN |
TIMEZONE |
No | America/New_York | Timezone |
SMTP_NETWORKS |
No | Auto /16 | Additional networks (comma-separated CIDR) |
SMTP_LISTEN_PORT |
No | 25 | Port to expose on host |
LOCAL_NETWORK |
No | Auto-detected | Override local network CIDR (e.g., 192.168.0.0/16) |
DEBUG |
No | no | Enable debug logging |
Provider Examples
Maileroo
SMTP_SERVER=smtp.maileroo.com
SMTP_PORT=587
SMTP_USERNAME=noreply@example.com
SMTP_PASSWORD=your_password
DOMAIN=example.com
Mailtrap
SMTP_SERVER=live.smtp.mailtrap.io
SMTP_PORT=587
SMTP_USERNAME=your_username
SMTP_PASSWORD=your_password
DOMAIN=example.com
SendGrid
SMTP_SERVER=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=your_api_key
DOMAIN=example.com
Note: For SendGrid, username must be apikey (literal string).
Gmail
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your_email@gmail.com
SMTP_PASSWORD=your_app_password
DOMAIN=gmail.com
Makefile Commands
All operations are handled through the Makefile in the test/ directory.
Setup Commands
cd test
make build # Build the Docker image
make up # Start the container
make down # Stop the container
make restart # Restart the container
Monitoring Commands
make logs # View logs (follow mode)
make logs-tail # View last 100 lines
make status # Show container and Postfix status
make queue # View mail queue
make health # Check container health
Maintenance Commands
make shell # Open shell in container
make config # Show Postfix configuration
make test # Send test email (auto-detects container)
make flush # Flush mail queue
make check # Validate Postfix configuration
Cleanup Commands
make clean # Remove container and volumes
make clean-all # Remove everything including images
Advanced Commands
make debug # Start with debug mode enabled
make validate # Validate .env file
make queue-delete # Delete all messages in queue
make stats # Show real-time container stats
Full Command List
Run make help or just make to see all available commands:
cd test
make
Network Configuration
The container automatically allows relay from:
- Localhost (127.0.0.0/8)
- Auto-detected /16 subnet
To add custom networks:
SMTP_NETWORKS=192.168.1.0/24,10.0.0.0/8
Using with Applications
Configure your application to use the relay:
services:
your-app:
environment:
MAIL_HOST: postfix-relay
MAIL_PORT: 25
depends_on:
- postfix
Connection details:
- Host:
postfix-relay - Port:
25 - Authentication: Not required for local network
Testing
Quick Test (Recommended)
The easiest way to test your Postfix relay:
cd test
make test TO=recipient@example.com
That's it! No configuration needed.
What Gets Auto-Detected?
The test script automatically finds and configures:
| Feature | What Happens | Override Option |
|---|---|---|
| Container Name | Finds containers using docker-postfix-postfix image |
Specify as first arg |
| FROM Address | Uses noreply@DOMAIN from container env |
FROM=email@domain.com |
| SMTP Port | Detects mapped port (e.g., 25 or custom) |
N/A (always detected) |
| Host IP | Converts 0.0.0.0 → 127.0.0.1 for local testing |
N/A (always detected) |
| Subject | Defaults to "Test Email from Postfix Relay" | SUBJECT="Your Subject" |
No manual configuration required - just provide the recipient email!
Advanced Testing Options
With custom FROM address:
make test TO=user@example.com FROM=noreply@mydomain.com
With custom subject:
make test TO=user@example.com FROM=sender@domain.com SUBJECT="My Test Email"
Using the test script directly:
./test-email.sh user@example.com
./test-email.sh user@example.com sender@mydomain.com
./test-email.sh user@example.com sender@mydomain.com "Custom Subject"
Manual container specification (if auto-detection fails):
./test-email.sh my-container user@example.com sender@domain.com
Test Script Features
The test-email.sh script automatically:
- Finds containers using
docker-postfix-postfiximage - Detects port mapping and converts
0.0.0.0to127.0.0.1 - Uses proper SMTP protocol via sendmail
- Falls back to mail command if needed
- Shows queue status after sending
- Provides colored output for easy reading
Validation Tests
cd test
make check # Validate Postfix configuration
make validate # Validate .env file
make queue # View mail queue
make config # Show current Postfix config
Troubleshooting
Email Not Received
1. Check container logs:
cd test
make logs-tail # Last 100 lines
make logs # Follow in real-time
2. Check mail queue:
make queue # View queued messages
make flush # Force processing
3. Verify configuration:
make config # Show Postfix config
make check # Validate config
make validate # Validate .env file
SMTP Protocol Errors
If you see "improper command pipelining" errors:
Use the test script (handles protocol correctly):
./test-email.sh user@example.com sender@domain.com
Verify FROM domain matches DOMAIN setting:
# In .env file
DOMAIN=mydomain.com
# Use matching FROM address
make test TO=user@example.com FROM=noreply@mydomain.com
Check mynetworks configuration:
docker exec postfix-relay postconf mynetworks
Container Not Auto-Detected
1. Verify container is running:
docker ps | grep postfix
2. Start the container:
cd test
make up
3. Manually specify container:
./test-email.sh my-container-name user@example.com
Enable Debug Mode
For detailed SMTP transaction logs:
cd test
make debug
Emails Stuck in Queue
cd test
make queue # View queue
make flush # Force processing
make queue-delete # Delete all (with confirmation)
Network Configuration Issues
Override auto-detected network:
# In .env file
LOCAL_NETWORK=192.168.1.0/24
Add additional networks:
SMTP_NETWORKS=10.0.0.0/8,172.16.0.0/12
Container Health Issues
cd test
make status # Check status
make health # Check health status
make restart # Restart container
make down # Stop container
make up # Start fresh
Examples
Testing Examples
Simple test with Gmail:
cd test
make test TO=youraddress@gmail.com
# FROM will auto-detect from DOMAIN in .env
Test with custom FROM and subject:
make test TO=client@example.com FROM=support@mycompany.com SUBJECT="Production Test"
Test from command line:
./test-email.sh user@example.com noreply@mydomain.com "Hello World"
Verify email was sent:
make queue # Should show empty queue if sent
make logs-tail # Check for "status=sent"
Basic Workflow
# Initial setup
cd docker-postfix
cp env.sample .env
nano .env
# Build and start
cd test
make build
make up
# Check status
make status
make logs
# Test email delivery
make test TO=your@email.com
# Stop
make down
Development Workflow
cd test
# Start with debug
make debug
# Check logs in another terminal
make logs
# Restart after changes
make restart
# Clean up
make clean
Monitoring Workflow
cd test
# Check everything
make status
make health
make queue
make logs-tail
# Continuous monitoring
make logs
Security
- Store credentials in
.env(never commit to git) - Limit relay to trusted networks only
- TLS automatically enabled for known providers
- Use app-specific passwords for Gmail
License
MIT License - See LICENSE file for details.
Support
For issues and questions, please open an issue on Gitea.