This repository provides a complete, Dockerized SMTP relay solution using Postfix and Cyrus SASL. It allows you to securely relay emails from client applications to an upstream SMTP server, with flexible authentication and TLS encryption options.
An SMTP relay forwards email messages from sending clients to another SMTP server. This is useful for:
- Centralizing email delivery from multiple applications or services.
- Securing authentication for client applications by offloading to a dedicated relay.
- Enforcing transport security with TLS for both incoming client connections and outgoing relay connections.
- Dockerfile
- Builds an Alpine-based image including Postfix (SMTP server) and Cyrus SASL (authentication).
- Prepares Postfix directories, configures permissions, and exposes SMTP ports.
- docker-entrypoint.sh
- Validates and injects environment variables for relay and client authentication.
- Generates SASL user databases, configures Postfix (
main.cfandmaster.cf) dynamically based on variables. - Starts Postfix in the foreground, logging to stdout.
- docker-compose.yml
- Generic Docker Compose setup for running the SMTP relay container.
- Exposes ports for plain/STARTTLS and SMTPS.
- Defines environment variables, TLS volume mounts, and a persistent mail spool.
- docker-compose-oauth2.yml
- Example Compose file integrating email-oauth2-proxy. (email-oauth2-proxy-docker)
- Offloads OAuth2 authentication (e.g., Google, Microsoft) to a proxy, enhancing security.
- Outgoing Relay (
RELAY_AUTH_METHOD):plain: No TLS enforced, simple authentication.starttls: Opportunistic or required STARTTLS on port 587.smtps: Implicit SSL/TLS on port 465.
- Incoming Client (
INCOMING_AUTH_METHOD):plain: Allows unencrypted SMTP (port 25).starttls: Clients must issue STARTTLS before authentication.smtps: Implicit TLS on port 465 for maximum security.
- Uses your provided
fullchain.pemandprivkey.pemcertificates. - Ensures encrypted transport for client connections and/or relay connections.
- Prevents eavesdropping and man-in-the-middle attacks.
- Automatically creates SASL user entries from
INCOMING_USERNAMEandINCOMING_PASSWORD. - Supports optional SASL realm (
REALM) for multi-tenant setups.
- A Docker volume
smtp-spoolpersists undelivered messages across container restarts. - Useful for handling temporary upstream outages without losing messages.
email-oauth2-proxy is an excellent solution for integrating the new mandatory authentication systems from Google and Microsoft with legacy SMTP clients. However, in some cases, security can be compromised. For example, when using Google APIs to send emails with the secret.json (service account secret), any password is accepted as valid, which is not secure. This approach adds an extra layer but it does fully solve the problem.
Additionally, at the time of writing this README, email-oauth2-proxy has a bug where it fails if the client sends EHLO localhost during the SMTP protocol handshake. Many clients do this — Gatus, for instance - and with smtp-relay the problem is solved.
- Docker ≥ 20.10
- Docker Compose ≥ 1.29
- Valid TLS certificates (
fullchain.pem,privkey.pem) for STARTTLS and SMTPS
cp /path/to/fullchain.pem ./
cp /path/to/privkey.pem ./
docker-compose -f docker-compose.yml up -dClients connect to:
- Port 2525 for
plainorstarttls. - Port 2465 for
smtps.
You can refer to this repo.
| Variable | Description |
|---|---|
RELAY_HOST |
Upstream SMTP host (e.g., smtp.gmail.com or your OAuth2 proxy). |
RELAY_PORT |
Upstream SMTP port (587, 465, or 25). |
RELAY_USERNAME |
Username for upstream authentication. |
RELAY_PASSWORD |
Password for upstream authentication. |
RELAY_AUTH_METHOD |
plain / starttls / smtps for relay. |
INCOMING_AUTH_METHOD |
plain / starttls / smtps for client connections. |
INCOMING_USERNAME |
SASL username for clients. |
INCOMING_PASSWORD |
SASL password for clients. |
REALM |
Optional SASL realm for multi-tenant services. |
- smtp-spool:
/var/spool/postfixpersists the mail queue. - fullchain.pem, privkey.pem: Mounted read-only to
/etc/ssl/certs&/etc/ssl/private.
Just treat it as a normal smtp server but the username must be INCOMING_USERNAME@REALM.
- Modify SMTP parameters with
postconfcommands indocker-entrypoint.sh. - To enable additional SASL mechanisms, adjust
/etc/sasl2/smtpd.conf. - Check logs via
docker logs smtp_relayfor runtime diagnostics.
- Implement no password authentication for complete legacy smtp clients and servers compatibility.
This project is licensed under the MIT License.
You are free to use, modify, and distribute this software, as long as the original copyright and license notice are included.
© Lorenzo Mirabella - SMTP Relay