Deploy SpamEater with all security features intact using Docker. This containerized version maintains 100% feature parity with the production AlmaLinux 9 setup.
You MUST configure DNS before running Docker installation. The SSL certificate generation will fail without proper DNS.
-
Domain ownership - You must own a domain (e.g.,
example.com) -
DNS Configuration (REQUIRED FIRST) - Configure these records before proceeding:
MX example.com 10 mail.example.com A mail.example.com YOUR_SERVER_IP A example.com YOUR_SERVER_IP (or app.example.com for subdomain) -
Verify DNS is working:
# Check MX record dig MX example.com # Should show: example.com. 3600 IN MX 10 mail.example.com. # Check A record dig A mail.example.com # Should show your server's IP address
-
Server requirements:
- Docker Engine 20.10+ and Docker Compose v2+
- Ports 25, 80, and 443 open and not in use
- Static IP address
Only after DNS is verified working:
# Clone the repository
git clone https://github.com/rufftruffles/spameater.git
cd spameater/docker
# Configure environment
cp .env.example .env
nano .env # Edit EMAIL_DOMAIN with your actual domain
# Deploy
docker compose up -d
# Check logs
docker compose logs -f- Web Interface:
https://your-domain.com(or subdomain) - Email:
anything@your-domain.com
| Variable | Required | Default | Description |
|---|---|---|---|
EMAIL_DOMAIN |
Yes | - | Domain for receiving emails (e.g., example.com) |
WEB_DOMAIN |
No | EMAIL_DOMAIN |
Domain for web access (e.g., mail.example.com) |
ADMIN_EMAIL |
No | admin@EMAIL_DOMAIN |
Email for Let's Encrypt notifications |
DELETE_TOKEN_SECRET |
No | Auto-generated | 32-character secret for delete tokens |
CSRF_SECRET |
No | Auto-generated | 32-character CSRF protection secret |
ENCRYPTION_KEY |
No | Auto-generated | 32-character encryption key |
DISABLE_SSL |
No | false |
Set to true for HTTP-only (development) |
AUTO_SSL |
No | true |
Auto-generate SSL certificates |
The compose file creates three persistent volumes:
spameater_data: Email database and JSON filesspameater_logs: Application logsletsencrypt_certs: SSL certificates
SSL certificate generation will fail if DNS is not properly configured. Make sure your domain points to your server's IP address before deploying.
The container automatically obtains Let's Encrypt certificates if:
- DNS is properly configured and propagated (most important)
- Ports 80/443 are accessible from internet
AUTO_SSLis not set tofalse
If SSL generation fails during first startup, it's usually because:
- DNS is not pointing to your server yet
- DNS hasn't propagated (can take up to 48 hours)
- Ports 80/443 are blocked by firewall
If automatic SSL fails or you prefer manual setup:
# Enter the container
docker exec -it spameater bash
# Run certbot manually
certbot --nginx -d your-domain.com --email admin@your-domain.com
# Restart nginx
nginx -s reloadFor local development without SSL:
# In .env file
DISABLE_SSL=true# All services
docker compose logs -f
# Specific service
docker compose logs -f spameater
# Inside container
docker exec -it spameater tail -f /opt/spameater/logs/haraka.log
docker exec -it spameater tail -f /opt/spameater/logs/api.log# Restart all
docker compose restart
# Inside container - individual services
docker exec -it spameater supervisorctl restart haraka
docker exec -it spameater supervisorctl restart spameater-api
docker exec -it spameater supervisorctl restart nginx# Check health
docker compose ps
# Inside container
docker exec -it spameater supervisorctl statusAll security features from the production setup are preserved:
- CSRF token protection
- Delete token authentication
- Email body encryption (AES-256-GCM)
- Rate limiting (nginx + application)
- Path traversal protection
- SQL injection prevention
- XSS protection
- ModSecurity WAF with OWASP CRS (enabled via EPEL/CRB repositories)
- fail2ban protection
- Security event logging
- Automatic cleanup after 24 hours
- Non-root user for application processes
- Minimal base image (AlmaLinux 9)
- No unnecessary packages
- Secrets management via environment variables
# Check logs
docker compose logs spameater
# Verify environment
docker compose config
# Check port availability
netstat -tulpn | grep -E ':(25|80|443)'-
Check DNS:
dig MX your-domain.com dig A mail.your-domain.com
-
Check Haraka:
docker exec -it spameater supervisorctl status haraka docker exec -it spameater tail -f /opt/spameater/logs/haraka.log
-
Test SMTP:
telnet your-server-ip 25
# Check certificate status
docker exec -it spameater certbot certificates
# Renew manually
docker exec -it spameater certbot renew
# Check nginx config
docker exec -it spameater nginx -t# Check database
docker exec -it spameater sqlite3 /opt/spameater/data/emails.db ".tables"
# Check permissions
docker exec -it spameater ls -la /opt/spameater/data/# Pull latest changes
git pull
# Rebuild and restart
docker compose build --no-cache
docker compose up -d
# Check new version
docker compose logs | head -20# Backup data volume
docker run --rm -v docker_spameater_data:/data -v $(pwd):/backup alpine \
tar czf /backup/spameater-backup-$(date +%Y%m%d).tar.gz -C /data .
# Backup certificates
docker run --rm -v docker_letsencrypt_certs:/certs -v $(pwd):/backup alpine \
tar czf /backup/certs-backup-$(date +%Y%m%d).tar.gz -C /certs .# Restore data
docker run --rm -v docker_spameater_data:/data -v $(pwd):/backup alpine \
tar xzf /backup/spameater-backup-YYYYMMDD.tar.gz -C /data
# Restore certificates
docker run --rm -v docker_letsencrypt_certs:/certs -v $(pwd):/backup alpine \
tar xzf /backup/certs-backup-YYYYMMDD.tar.gz -C /certs- Minimum: 1 CPU, 1GB RAM, 10GB disk
- Recommended: 2 CPU, 2GB RAM, 20GB disk
- OS: Any Linux with Docker support
- Use Docker secrets for sensitive data instead of environment variables
- Enable firewall on host system
- Regular updates: Keep Docker and base image updated
- Monitor logs: Set up log aggregation
- Rate limiting: Adjust nginx rate limits based on usage
For high-volume deployments:
# docker-compose.override.yml
services:
spameater:
deploy:
replicas: 2
resources:
limits:
cpus: '4'
memory: 4G| Feature | Native | Docker | Notes |
|---|---|---|---|
| Base OS | AlmaLinux 9 | AlmaLinux 9 | Same |
| Services | systemd | supervisord | Equivalent functionality |
| Firewall | firewalld | Host firewall | Configure on host |
| SSL | certbot | certbot | Same, persisted in volume |
| ModSecurity | Yes | Yes | Enabled via EPEL/CRB repositories |
| fail2ban | Yes | Limited | Requires privileged mode |
- Issues: GitHub Issues
- Security: Report via GitHub Security tab
MIT License - See LICENSE file
Remember: All emails auto-delete after 24 hours. No exceptions.