Enterprise-grade Postfix on a distroless base: DB/LDAP maps, TLS 1.2-1.3, DANE, SASL, hardened
1.5K
Everything needed to deploy and operate
euca01/postfix-distroless
— enterprise-grade Postfix on a distroless base (no shell, no package
manager, amd64/arm64, hardened by default, built and fully tested
automatically for every upstream release).
This repository contains deployment material only: compose files, examples and operating documentation. The container images are prebuilt and published on Docker Hub.
git clone <this-repo> postfix && cd postfix
cp .env.example .env && $EDITOR .env # image tag + hostname
docker compose up -d
That's it:
./config/ is seeded with the commented, hardened
configuration of your exact image version — edit the real Postfix
files there and apply live with docker kill -s HUP postfix;docker run --rm euca01/postfix-distroless:3.11.6-r2 config-template | tar -x -C ./config
| Path | Purpose |
|---|---|
docker-compose.yml | Production-hardened single-MTA deployment (env-driven) |
.env.example | The two settings you must choose: image tag, hostname |
config/ | Your Postfix configuration (seeded on first start, then yours) |
examples/relay.compose.yml | Minimal outbound relay (smarthost) |
examples/mx-dovecot-sasl.compose.yml | MX + Dovecot SASL for authenticated submission (587) |
examples/rspamd-milter.compose.yml | MX + Rspamd spam filtering (fail-closed milter) |
docs/CONFIGURATION.md | Full configuration reference: layers, templates, TLS, SASL, lookup tables |
docs/OPERATIONS.md | Runbook: go-live checklist, runtime security spec, -debug variants, maintenance contract, upgrades/rollback, troubleshooting |
SECURITY.md | Vulnerability reporting, CVE handling policy, rebuild SLA |
CHANGELOG.md | Release notes per image revision |
| Tag | Meaning | Use |
|---|---|---|
3.11.6-r2 | Immutable build, never overwritten | Production |
3.11.6 | Latest rebuild of that patch (moves on dependency updates) | Patch-pinned |
3.11 | Latest patch of the line | Line tracking |
stable, latest | Current stable line | Evaluation |
3.11.6-r2-debug, 3.11-debug, debug | Same rootfs + busybox shell (distroless :debug base) | Incident diagnosis only |
Published lines: 3.11 (stable), 3.10, 3.9, 3.8 (legacy). Every
upstream release and every dependency update (OpenSSL, …) is rebuilt,
passed through the full test pyramid (unit + 43 integration + 18
E2E/chaos assertions on both architectures), scanned (Trivy, blocking on
fixable CRITICAL/HIGH) and published automatically.
Base image: gcr.io/distroless/cc-debian12 (Google distroless,
digest-pinned in the build). The C runtime (glibc, libssl carried by the
image) comes from Debian 12 packages, rebuilt into a new -rN
revision as soon as Debian ships a security update — patching is owned by
this pipeline, not by waiting for a base-image refresh.
| Action | Command |
|---|---|
| Queue status / flush | docker exec postfix /usr/sbin/postqueue -p · -f |
| Effective configuration | docker exec postfix /usr/sbin/postconf -n |
| Test a lookup table | docker exec postfix /usr/sbin/postmap -q KEY type:/etc/postfix/file |
| Reload configuration | docker kill -s HUP postfix |
| Graceful stop | docker stop --timeout 30 postfix (exit 0) |
| Logs | docker logs postfix |
There is no shell in the image: docker exec works with absolute binary
paths only.
Full references: docs/CONFIGURATION.md · docs/OPERATIONS.md · SECURITY.md · CHANGELOG.md
Content type
Image
Digest
sha256:2d48cff26…
Size
22.1 MB
Last updated
about 2 months ago
docker pull euca01/postfix-distroless