Sign inSign up

01it/postfix

By 01it

•Updated 40 minutes ago

Minimalistic Postfix mail server with TLS and relay support

Image
Networking
Developer tools
0

9.9K

01it/postfix repository overview

⁠Postfix Docker Image

Docker Pulls Docker Stars GitHub release

Lightweight Postfix mail relay with built-in DKIM signing, TLS support, and flexible delivery modes.

⁠Features

  • Direct delivery — send mail directly to recipient MX servers (default)
  • Relay mode — forward mail through an external SMTP provider (AWS SES, Gmail, etc.)
  • DKIM signing — embedded OpenDKIM with automatic key generation
  • TLS — auto-generated self-signed certs or Let's Encrypt
  • Configurable — all settings via environment variables
  • Minimal — multi-stage Debian Trixie build
  • Multi-arch — linux/amd64 and linux/arm64

⁠Quick Start

docker run -d --name postfix \
  -e DOMAIN=example.com \
  -e MAILNAME=mail.example.com \
  -p 25:25 -p 587:587 \
  -v dkim_keys:/etc/ssl/dkim \
  01it/postfix:latest

On first startup, the container will:

  1. Generate a DKIM key pair and print the DNS TXT record to stdout
  2. Generate self-signed TLS certificates
  3. Start OpenDKIM and Postfix

Check logs for the DKIM public key:

docker logs postfix 2>&1 | grep -A2 "DKIM PUBLIC KEY"

⁠Operation Modes

⁠Direct Delivery (default)

Mail is delivered directly to recipient MX servers over port 25. This is the default when RELAY_HOST is not set.

Requirements:

  • Outbound port 25 must be open (blocked by most cloud providers by default)
  • Proper DNS records configured (see DNS Records⁠)
⁠Relay Mode

Mail is forwarded through an external SMTP provider. Activated by setting RELAY_HOST.

environment:
  - RELAY_HOST=[smtp.example.com]:587
  - SMTP_USERNAME=your-username
  - SMTP_PASSWORD=your-password
⁠Authenticated Submission

Port 587 always requires a SASL account from SMTP_AUTH_USERS, including clients inside MY_NETWORKS. Trusted networks can still relay without a login on port 25.

environment:
  - SMTP_AUTH_USERS=alice:s3cret,bob:hunter2
ports:
  - "587:587"

Clients authenticate over STARTTLS with the bare username (e.g. alice) and password. Accounts are re-provisioned from the environment on every start, so update the variable and recreate the container to change credentials.

⁠Configuration

⁠Core Settings
VariableDefaultDescription
DOMAINexample.comDomain for DKIM signing
MAILNAMEmail.example.comPostfix hostname (myhostname) and Let's Encrypt certificate name
MY_NETWORKS127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16Trusted networks allowed to relay on port 25
MY_DESTINATION_DOMAINS—Additional local destination domains
SMTP_AUTH_USERS—Submission (587) login accounts, user1:pass1,user2:pass2
⁠DKIM Settings
VariableDefaultDescription
DKIM_SELECTORmailDKIM selector (used in DNS record name)
DKIM_KEY_DIR/etc/ssl/dkimDirectory for DKIM key storage
DKIM_EXTRA_DOMAINS—Comma-separated extra domains to DKIM-sign (same key)
⁠Relay Settings
VariableDefaultDescription
RELAY_HOST—External SMTP relay (e.g., [smtp.gmail.com]:587)
SMTP_USERNAME—Relay authentication username
SMTP_PASSWORD—Relay authentication password
FALLBACK_RELAY_HOST—Fallback relay when primary delivery fails (e.g., [backup-smtp.example.com]:587)
FALLBACK_SMTP_USERNAME—Fallback relay authentication username
FALLBACK_SMTP_PASSWORD—Fallback relay authentication password
⁠TLS Settings
VariableDefaultDescription
LETSENCRYPT_EMAIL—Enables Let's Encrypt; email for account registration
LETSENCRYPT_EXTRA_DOMAINS—Comma-separated extra domains for the certificate (SANs)
SSL_COUNTRYUSSelf-signed certificate country
SSL_STATEStateSelf-signed certificate state
SSL_LOCALITYCitySelf-signed certificate locality
SSL_ORGANIZATIONOrganizationSelf-signed certificate organization
SSL_ORGANIZATIONAL_UNITITSelf-signed certificate OU
⁠Dynamic Postfix Configuration

Any Postfix directive can be set via POSTFIX_ prefix:

environment:
  - POSTFIX_message_size_limit=52428800
  - POSTFIX_smtp_helo_name=mail.example.com

⁠DNS Records

For reliable mail delivery, configure these DNS records for your domain:

⁠PTR (Reverse DNS)

Your server's IP must have a PTR record matching MAILNAME. Set this at your hosting provider.

203.0.113.1 → mail.example.com
⁠SPF

Authorizes your server to send mail for your domain.

example.com.  IN  TXT  "v=spf1 mx ip4:203.0.113.1 -all"
⁠DKIM

The container prints the DKIM public key on first startup. Add it as a TXT record:

mail._domainkey.example.com.  IN  TXT  "v=DKIM1; k=rsa; p=<PUBLIC_KEY>"

Replace mail with your DKIM_SELECTOR if different.

⁠DMARC

Controls how receivers handle authentication failures.

_dmarc.example.com.  IN  TXT  "v=DMARC1; p=quarantine; rua=mailto:[email protected]"

⁠Let's Encrypt

For production use, real TLS certificates improve deliverability. Set LETSENCRYPT_EMAIL to enable:

environment:
  - [email protected]
  - MAILNAME=mail.example.com
  - LETSENCRYPT_EXTRA_DOMAINS=smtp.example.com
ports:
  - "80:80"    # Required for HTTP-01 challenge
  - "25:25"
  - "587:587"
volumes:
  - letsencrypt:/etc/letsencrypt

The certificate is issued for MAILNAME, plus any LETSENCRYPT_EXTRA_DOMAINS. DOMAIN is not added automatically: it is the DKIM domain, and HTTP-01 fails when that name is behind a CDN. Every name on the certificate must have DNS that reaches this host on port 80 and must not be proxied. Certificates are issued with acme.sh⁠ (HTTP-01, standalone). Mount the letsencrypt volume to persist the acme.sh account and certificates across restarts. If issuance fails, the container falls back to self-signed certificates.

⁠Volumes

VolumePathDescription
postfix_data/var/spool/postfixMail queue and spool data
postfix_certs/etc/ssl/postfixSelf-signed TLS certificates
dkim_keys/etc/ssl/dkimDKIM private/public key pair
letsencrypt/etc/letsencryptLet's Encrypt certificates (optional)

⁠Ports

PortProtocolDescription
25SMTPStandard mail delivery (direct mode) and receiving
587SubmissionAuthenticated submission with STARTTLS

⁠Cloud Provider Notes

Most cloud providers block outbound port 25 by default:

  • AWS: Request removal of port 25 restriction via support ticket
  • GCP: Blocked; use a relay or third-party SMTP service
  • Azure: Blocked on Basic/Standard tiers; use SendGrid or relay

If port 25 is blocked, use relay mode with an external SMTP provider.

⁠Security

  • TLS 1.2+ enforced (SSLv2, SSLv3, TLSv1, TLSv1.1 disabled)
  • High-strength ciphers only
  • DKIM signing for outbound mail
  • Port 587 requires a SASL account from SMTP_AUTH_USERS over STARTTLS. Port 25 still relays for MY_NETWORKS without a login.
  • Proper sender/recipient restrictions
  • Minimal base image

⁠Logs

All logs go to stdout:

docker logs -f postfix

⁠Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

⁠License

This project is licensed under the MIT License - see the LICENSE file for details.

Tag summary

Content type

Image

Digest

sha256:12d4ba30f…

Size

488 Bytes

Last updated

40 minutes ago

docker pull 01it/postfix:sha256-cf3cb44b27180c0ffadebfdcae348767e6f8ac194e3aee0bc9b05a0260efdf8f.sig