Sign inSign up

arcclaro/postfix-relay

By arcclaro

•Updated 2 days ago

Minimal, secure Alpine-based Postfix SMTP relay. Zero CVEs, weekly rebuilt.

Image
0

1.3K

arcclaro/postfix-relay repository overview

⁠postfix-relay

Build and Push Docker Pulls Docker Image Size Zero Vulnerabilities

Minimal, secure Alpine-based Postfix SMTP relay for Docker. Designed as a drop-in replacement for the almost perfect boky/postfix with zero known HIGH or CRITICAL vulnerabilities and automated weekly rebuilds.

⁠Why

Most Postfix relay images are built on Debian or stale Alpine bases, accumulating CVEs over time while waiting for maintainer rebuilds. This image:

  • Builds on Alpine Linux latest — minimal attack surface
  • Rebuilds weekly via GitHub Actions — picks up OS/OpenSSL/Postfix patches automatically
  • Runs Trivy scan on every build — fails if CRITICAL or HIGH CVEs are found
  • Ships no unnecessary components — no supervisor, no rsyslog, no opendkim
  • Uses postfix start-fg as PID 1 — proper Docker signal handling
  • Logs to stdout natively — works with docker logs out of the box

⁠Quick start

services:
  smtp-relay:
    image: arcclaro/postfix-relay:latest
    container_name: smtp-relay
    restart: unless-stopped
    environment:
      ALLOWED_SENDER_DOMAINS: "example.com"
      RELAYHOST: "smtp.example.com:587"
      RELAYHOST_USERNAME: "[email protected]"
      RELAYHOST_PASSWORD: "your-smtp-password"
    ports:
      - "127.0.0.1:2525:587"

Send a test email:

swaks --to [email protected] \
      --from [email protected] \
      --server 127.0.0.1 \
      --port 2525 \
      --body "Test email"

⁠Configuration

⁠Environment variables
VariableRequiredDefaultDescription
ALLOWED_SENDER_DOMAINS✅*—Space-separated list of permitted sender domains
ALLOW_EMPTY_SENDER_DOMAINS——Set to any value to bypass sender domain restriction
RELAYHOST——Upstream relay as host:port. If unset, delivers directly
RELAYHOST_USERNAME——SASL username for relay authentication
RELAYHOST_PASSWORD——SASL password for relay authentication
RELAYHOST_TLS_LEVEL—encryptTLS level for relay connection (encrypt, may, none)
MASQUERADE_DOMAINS——Rewrite sender domain (e.g. hide internal hostnames)
MASQUERADE_EXCEPTIONS—rootAccounts excluded from masquerading
MESSAGE_SIZE_LIMIT—26214400 (25MB)Maximum message size in bytes
MYNETWORKS—RFC1918 rangesNetworks allowed to relay without authentication
HOSTNAME—reverse DNS or postfix-relayPostfix myhostname
INET_PROTOCOLS—ipv4IP protocols to use (ipv4, ipv6, all)
SMTP_HEADER_CHECKS——Path to header checks file, or 1 for default location
INBOUND_DEBUGGING——Set to any value to enable verbose debug logging

*Required unless ALLOW_EMPTY_SENDER_DOMAINS is set.

⁠Ports
PortDescription
587Submission (primary)
25SMTP (also available inside container)

⁠Usage examples

⁠Relay
services:
  smtp-relay:
    image: arcclaro/postfix-relay:latest
    container_name: smtp-relay
    restart: unless-stopped
    hostname: smtp.example.com
    environment:
      ALLOWED_SENDER_DOMAINS: "example.com example.org"
      RELAYHOST: "mail.example.com:587"
      RELAYHOST_USERNAME: "[email protected]"
      RELAYHOST_PASSWORD: "your-mailbox-password"
      MASQUERADE_DOMAINS: "example.com"
      MESSAGE_SIZE_LIMIT: "52428800"
    ports:
      - "127.0.0.1:2525:587"
    networks:
      - smtp-network

networks:
  smtp-network:
    driver: bridge
⁠Direct delivery (no relay)
services:
  smtp-relay:
    image: arcclaro/postfix-relay:latest
    container_name: smtp-relay
    restart: unless-stopped
    environment:
      ALLOWED_SENDER_DOMAINS: "example.com"
      MESSAGE_SIZE_LIMIT: "26214400"
    ports:
      - "127.0.0.1:2525:587"
⁠Custom display name via header checks

Rewrite the From display name for all outbound mail regardless of the sending service:

services:
  smtp-relay:
    image: arcclaro/postfix-relay:latest
    container_name: smtp-relay
    restart: unless-stopped
    environment:
      ALLOWED_SENDER_DOMAINS: "example.com"
      RELAYHOST: "mail.example.com:587"
      RELAYHOST_USERNAME: "[email protected]"
      RELAYHOST_PASSWORD: "your-password"
      SMTP_HEADER_CHECKS: "regexp:/etc/postfix/smtp_header_checks"
    volumes:
      - ./smtp_header_checks:/etc/postfix/smtp_header_checks:ro
    ports:
      - "127.0.0.1:2525:587"

smtp_header_checks:

# Rewrite all senders to a single display name
/^From:.*@example\.com/    REPLACE From: My App <[email protected]>
/^From:.*@example\.org/    REPLACE From: My App <[email protected]>
⁠IPv6 support
environment:
  INET_PROTOCOLS: "all"   # ipv4, ipv6, or all
⁠Multi-service Docker Compose setup

Internal services connect to the relay on the shared network without authentication:

services:
  smtp-relay:
    image: arcclaro/postfix-relay:latest
    container_name: smtp-relay
    restart: unless-stopped
    environment:
      ALLOWED_SENDER_DOMAINS: "example.com"
      RELAYHOST: "mail.example.com:587"
      RELAYHOST_USERNAME: "[email protected]"
      RELAYHOST_PASSWORD: "your-password"
    networks:
      - smtp-network

  my-app:
    image: my-app:latest
    environment:
      SMTP_HOST: smtp-relay
      SMTP_PORT: 587
    networks:
      - smtp-network

networks:
  smtp-network:
    driver: bridge
⁠Extending with custom init scripts

Mount scripts into /docker-init.d/ — they run before Postfix starts:

volumes:
  - ./custom-postfix.sh:/docker-init.d/custom-postfix.sh:ro

custom-postfix.sh:

#!/bin/sh
postconf -e "address_verify_negative_cache=yes"

⁠Connecting services

Services on the same Docker network connect without authentication:

SettingValue
SMTP hostsmtp-relay (container name)
SMTP port587
Username(empty)
Password(empty)
TLS(disabled — internal network)

⁠Vulnerability scanning

Every build runs Trivy against the published image. The workflow fails if any CRITICAL or HIGH CVE is found, preventing vulnerable images from reaching Docker Hub.

# Scan manually
trivy image arcclaro/postfix-relay:latest --severity HIGH,CRITICAL

⁠Tags

TagDescription
latestLatest build from main branch
1, 1.0, 1.0.0Versioned releases

⁠License

MIT

Tag summary

Content type

Image

Digest

sha256:4fdd3aecd…

Size

12 MB

Last updated

2 days ago

docker pull arcclaro/postfix-relay