Local parts are ASCII-folded — never str.lower(), which maps U+212A onto "k" and would resolve a look-alike to someone else's mailbox — for everything we own or resolve: mailbox lookup, login identity, inbound recipients. Domains are IDNA-canonicalized. Addresses we merely carry, in contacts and MIME headers, keep the case they were typed or received in. core.mda.addresses is the single policy, held in place by a pylint checker and an eslint rule that ban hand-rolled '@' splits and Unicode case folding. Migration 0035 folds existing rows and reports the collisions it will not merge on its own. Also drops mta-out, and adds dual RSA+ECDSA certificates, per-refusal logging and an mta_session correlation claim to mta-in.
8.6 KiB
Self-Hosting Guide
This guide explains how to deploy Messages in production, focusing on Messages-specific configuration and architecture.
Overview
Messages is designed to be self-hosted. See Architecture for component details.
Prerequisites
- Domain name(s) for your email service
- SSL certificates for your domains
- Server resources: Minimum 4GB RAM
Deployment Options
Messages supports multiple deployment strategies depending on your infrastructure and expertise level:
Docker Compose (Recommended for most users)
Best for: Small to medium deployments, single-server setups, quick prototyping
Requirements:
- Docker and Docker Compose installed
- Single server or VM with sufficient resources
- Basic Docker knowledge
Process:
- Start from the
compose.yamlin the repository - Create production environment files (
deploy/env/production/*.defaults) - Deploy to any environment where Docker Compose runs
- Configure DNS and SSL certificates
Advantages:
- Simplest setup and maintenance
- Easy to understand and modify
- Quick deployment and updates
- Good for development and testing
Ansible Deployment
Best for: Multi-server deployments, infrastructure automation, production environments
Requirements:
- Ansible knowledge
- Target servers with Docker support
- Infrastructure automation experience
Process:
- Use our ST Ansible repository as a base
- Customize playbooks for your infrastructure
- Deploy across multiple servers with automation
- Configure monitoring and backup strategies
Advantages:
- Infrastructure as code
- Automated deployment and updates
- Multi-server support
- Production-ready with monitoring
Kubernetes Deployment
Best for: Large-scale deployments, cloud-native environments, enterprise setups
Requirements:
- Kubernetes cluster
- Helm knowledge (when charts become available)
- Container orchestration experience
Process:
- Wait for Helm charts (coming in future releases)
- Deploy to Kubernetes cluster
- Configure ingress controllers and load balancers
- Set up monitoring with Prometheus/Grafana
Advantages:
- High availability and scalability
- Advanced orchestration features
- Cloud-native deployment patterns
- Enterprise-grade monitoring and logging
Note: Kubernetes deployment might be supported in future releases with official Helm charts.
Messages-Specific Configuration
1. Technical Domain Setup
Messages uses a technical domain concept for DNS infrastructure:
# Set your technical domain
MESSAGES_TECHNICAL_DOMAIN=mail.yourdomain.com
Technical Domain DNS Records:
mx1.mail.yourdomain.com. A YOUR_SERVER_IP
mx2.mail.yourdomain.com. A YOUR_SERVER_IP
_spf.mail.yourdomain.com. TXT "v=spf1 ip4:YOUR_SERVER_IP -all"
Customer Domain DNS Records:
@ MX 10 mx1.customer-domain.com.
@ MX 20 mx2.customer-domain.com.
@ TXT "v=spf1 include:_spf.mail.yourdomain.com -all"
_dmarc TXT "v=DMARC1; p=reject; adkim=s; aspf=s;"
The DNS records for each customer domains are available either via API at http://localhost:8901/api/v1.0/maildomains/{maildomain-uuid}/ or in the admin interface at http://localhost:8900/domain
2. Environment Configuration
Messages uses environment variables as the primary configuration method:
Environment File Structure:
deploy/env/production/backend.defaults- Main Django application settingsdeploy/env/production/frontend.defaults- Frontend configurationdeploy/env/production/mta-in.defaults- Inbound mail server settingsdeploy/env/production/postgresql.defaults- Database configurationdeploy/env/production/keycloak.defaults- Identity provider settings
For detailed environment variable documentation, see Environment Variables.
3. MTA Configuration
MTA-in (Inbound Email)
- Configured via
deploy/env/production/mta-in.defaults - Uses custom milter for synchronous delivery during SMTP sessions
- Validates recipients via REST API before accepting messages
Outbound Email
- Configured via
MTA_OUT_*indeploy/env/production/backend.defaults MTA_OUT_MODE=directdelivers straight to each recipient's MX (the default)MTA_OUT_MODE=relaysends everything throughMTA_OUT_RELAY_HOSTinstead
4. DNS Management
Messages includes automated DNS management:
# Check DNS records for a customer domain
python manage.py dns_check --domain example.com
# Provision DNS records automatically
python manage.py dns_provision --domain example.com --provider scaleway
# Simulate provisioning without making changes
python manage.py dns_provision --domain example.com --pretend
Supported DNS Providers:
- Scaleway DNS (full automation support)
5. Domain and Mailbox Management
Creating Mail Domains
# Via Django admin at /admin/
# Via API endpoints
# Via management commands
python manage.py shell
>>> from core.models import MailDomain
>>> MailDomain.objects.create(name='customer-domain.com')
Mailbox Creation
- Manual creation through admin interface
- Automatic creation via OIDC integration
- Programmatic creation via API
6. Identity Management
Messages uses OpenID Connect (OIDC) for user authentication. This is the only authentication method supported.
OIDC Configuration Options:
-
Bundled Keycloak (Recommended for most deployments)
- Keycloak is included in the default Docker Compose setup
- Pre-configured with Messages realm and users
- Suitable for organizations wanting a self-hosted identity provider
- Configure via
deploy/env/production/keycloak.defaults - See the identity provider guide to create the realm and the clients
-
External OIDC Provider
- Use any OIDC-compliant identity provider
- Examples: Auth0, Okta, Azure AD, Google Workspace
- Configure via
deploy/env/production/backend.defaults - Requires proper OIDC endpoint configuration
User Management:
- Users are created automatically when they first log in via OIDC
- Mailboxes can be created automatically based on OIDC email addresses
- A mail domain with
oidc_autojoingives each user a mailbox at login. This needs noIDENTITY_PROVIDER. - A mail domain with
identity_syncpushes each mailbox to Keycloak. See the identity provider guide
7. Production Deployment
For production deployment, create your own Docker Compose configuration based on compose.yaml:
Key Considerations:
- Use production environment files (
deploy/env/production/*.defaults) - Configure SSL/TLS certificates
- Set up persistent volumes for databases
- Implement proper restart policies
- Configure reverse proxy (Caddy) for SSL termination
Security Considerations
Messages-Specific Security
- MDA API Secret: Use strong, unique
MDA_API_SECRET - OIDC Configuration: Properly configure Keycloak endpoints
- Technical Domain: Secure DNS records for your technical domain
- Environment Files: Never commit production secrets
IP Reputation Management
Monitoring:
- Check your server's IP reputation at MXToolbox
- Monitor key blacklists: Spamhaus, Barracuda, SORBS
Recovery from Blacklisting:
- Stop all outgoing email immediately
- Check server logs for abuse indicators
- Follow blacklist's delisting procedure
- Implement stricter authentication and rate limiting
Troubleshooting
Common Messages Issues
-
MTA-in not receiving emails
- Check firewall settings for port 25
- Verify DNS MX records point to your technical domain
- Check MTA-in logs for API connection issues
-
Outbound mail not being sent
- Check the Celery worker logs — delivery runs there, not in a separate service
- Inspect per-recipient
delivery_status/delivery_messageon the message - In relay mode, verify
MTA_OUT_RELAY_HOSTand its credentials
-
DNS issues
- Use
dns_checkcommand to verify records - Ensure technical domain A records are correct
- Check DNS propagation with
dig
- Use
-
Authentication problems
- Verify Keycloak configuration in environment files
- Check OIDC endpoint URLs
- Review backend logs for authentication errors
Next Steps
After setting up your production environment:
- Test thoroughly with a small group of users
- Monitor performance and adjust resources as needed
- Set up automated backups and monitoring
- Plan for scaling as your user base grows
For additional help, join the Matrix community!