Files
unkin-agent 8736092555
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
Scaffold postfix smarthost image
2026-10-12 00:32:49 +11:00

52 lines
2.3 KiB
Markdown

# container-postfix
Postfix smarthost for the k8s `mail` namespace: takes inbound mail from the DMZ gateways
over WireGuard, delivers it to Stalwart over LMTP, and relays outbound mail to the
gateways. Built on each `container-base` distro image and published as
`artifactapi.k8s.syd1.au.unkin.net/docker-internal/postfix:<version>-<suffix>`; the
default distro's build is retagged as the unsuffixed `:<version>`, so both resolve to one
digest. Only explicit versions are published; never a floating tag.
| distro | from | tag suffix | default |
| --- | --- | --- | --- |
| `alma9` | `docker-internal/almalinux9:<base version>` | `alma9` | yes |
Ships only `postfix`, `postfix-lmdb` and `postfix-pcre`: `hash`, `lmdb`, `regexp`, `pcre`
(plus `texthash`/`inline`) maps and TLS. No site config is baked in.
## Running
- `CMD` is `postfix start-fg`; logs go to stdout (`maillog_file = /dev/stdout`, which a
mounted `main.cf` must keep).
- Mount `main.cf`, `master.cf` and maps from ConfigMaps as individual files (`subPath`)
under `/etc/postfix`; a whole-directory mount hides `dynamicmaps.cf`, which the lmdb and
pcre modules need. ConfigMaps are read-only, so prefer `texthash:`/`regexp:`/`pcre:`;
`hash:`/`lmdb:` maps need `postmap` into a writable path.
- Put `/var/spool/postfix` on a volume; missing queue directories are created on start.
- Postfix's master must run as root (it drops to `postfix` per service); minimum
capabilities: `CHOWN DAC_OVERRIDE FOWNER SETUID SETGID NET_BIND_SERVICE`.
## Tests
`test/smoke.sh` runs in the Dockerfile's `test` stage (CI `build`, `make test`): `postfix
check` on a sample config, then one STARTTLS message via `swaks` through every map type
to an `smtp-sink` LMTP listener, from an empty spool.
The `container-base` release this image builds on is `BASE_VERSION` in the `Dockerfile`.
## Adding a distro
1. `distros/<name>/distro.env` — `BASE_IMAGE_NAME`, `IMAGE`, `TAG_SUFFIX`, `DEFAULT`, `PACKAGES`.
2. One `include` entry in each of `.woodpecker/{build,docker}.yaml`.
The `check-distros` pre-commit hook fails if step 1 or 2 is incomplete, or if more than
one distro claims `DEFAULT`.
## Make
make build # build every distro
make test # build every distro's test stage
make pre-commit # uvx pre-commit run --all-files
make build-alma9 # one distro
make patch|minor|major