Messages: MTA Configuration¶
Messages includes two Postfix-based MTA containers for email handling.
MTA-in (Inbound)¶
Receives emails via SMTP on port 25 and delivers them to the Django backend through a custom milter.
mta-in:
image: ghcr.io/suitenumerique/messages-mta-in:main
user: root # Required for milter socket permissions
environment:
MYHOSTNAME: mx.<domain>
MDA_API_BASE_URL: http://backend:8000/api/v1.0/
MDA_API_SECRET: <mda-secret>
MAX_INCOMING_EMAIL_SIZE: 30000000
ports: ["25:25"]
Critical: user: root is required. Without it, the milter socket (/var/spool/postfix/milter/delivery.sock) has a permission mismatch and Postfix rejects all incoming email with 451 4.7.1 Service unavailable.
MTA-out (Outbound)¶
Relays outgoing emails to Brevo. The backend sends to Brevo directly (not through MTA-out) to avoid TLS certificate issues.
mta-out:
image: ghcr.io/suitenumerique/messages-mta-out:main
user: root
entrypoint: ["/bin/sh", "-c", "mkdir -p /var/spool/postfix/etc && chown -R postfix:postfix ... && exec /usr/local/bin/entrypoint.sh"]
environment:
MYHOSTNAME: mx.<domain>
SMTP_USERNAME: messages
SMTP_PASSWORD: <mta-password>
SMTP_RELAY_HOST: smtp-relay.brevo.com:587
SMTP_RELAY_USERNAME: <brevo-username>
SMTP_RELAY_PASSWORD: <brevo-password>
Two fixes required:
user: root— the entrypoint creates SASL password files in/var/spool/postfix/etc/which must exist before Postfix starts- Custom entrypoint — creates the directory and fixes ownership before running the original entrypoint
Backend Outbound Path¶
The Django backend sends outbound emails directly to Brevo, bypassing MTA-out:
MTA_OUT_MODE=relay
MTA_OUT_RELAY_HOST=smtp-relay.brevo.com:587
MTA_OUT_RELAY_USERNAME=<brevo-username>
MTA_OUT_RELAY_PASSWORD=<brevo-password>
This avoids TLS handshake issues with MTA-out's self-signed snakeoil certificate. The MTA-out container still runs for any internal SMTP submission needs.
Firewall¶
Inbound port 25 must be open:
- Hetzner Cloud: Add TCP/25 inbound rule in the Cloud Firewall
- Other VPS: Check provider's firewall settings
Outbound port 25 is NOT needed — all outbound email uses Brevo on port 587.