MIMEDefang postfix images
616
MIMEDefang email filter running alongside Postfix as the MTA, maintained by The McGrail Foundation.
MIMEDefang hooks into Postfix via the Milter protocol (smtpd_milters) and
lets you express your mail-filtering policy in Perl — stripping attachments,
adding headers, calling SpamAssassin, querying external APIs, and more.
| Tag | Purpose |
|---|---|
latest | Current stable release – production image (no build tools) |
vX.Y | Pinned release, e.g. v3.7 |
ci | CI/CD image – full build toolchain kept |
docker run -d \
-e MAIL_DOMAIN=example.com \
-e MAIL_HOST=mail.example.com \
-v /path/to/my-filter:/etc/mail/mimedefang-filter:ro \
-p 25:25 \
mimedefang/postfix:latest
If no filter is bind-mounted, a built-in pass-through filter is used so the container starts cleanly out of the box.
services:
postfix:
image: mimedefang/postfix:latest
hostname: mail.example.com
restart: unless-stopped
environment:
MAIL_DOMAIN: "example.com"
MAIL_HOST: "mail.example.com"
TZ: "Europe/Rome"
ports:
- "25:25"
volumes:
- ./mimedefang-filter:/etc/mail/mimedefang-filter:ro
- postfix-spool:/var/spool/MIMEDefang
- postfix-quarantine:/var/spool/MD-Quarantine
volumes:
postfix-spool:
postfix-quarantine:
All variables have sensible defaults; override only what you need.
| Variable | Default | Description |
|---|---|---|
MAIL_DOMAIN | example.com | mydomain in main.cf |
MAIL_HOST | mail.example.com | myhostname in main.cf |
RELAY_HOST | (empty) | Optional relayhost, e.g. [smtp.isp.com]:587 |
RELAY_NETS | 127.0.0.0/8 [::1]/128 | mynetworks — hosts allowed to relay |
| Variable | Default | Description |
|---|---|---|
MIN_WORKERS | 2 | Minimum number of Perl worker processes |
MAX_WORKERS | 10 | Maximum number of Perl worker processes |
MAX_IDLE | 2 | Workers to keep alive when idle |
SPOOL_DIR | /var/spool/MIMEDefang | Multiplexor and milter socket directory |
| Variable | Default | Description |
|---|---|---|
SMTP_PORT | 25 | SMTP listen port (informational; also set in ports:) |
ENABLE_SUBMISSION | no | Set to yes to enable port 587 submission service |
| Variable | Default | Description |
|---|---|---|
TZ | UTC | Container timezone, e.g. Europe/Rome |
| Mount path | Purpose |
|---|---|
/etc/mail/mimedefang-filter | Your Perl filter — bind-mount required for non-trivial use |
/etc/postfix/extra.cf | Optional: extra key = value lines appended to main.cf at startup |
/var/spool/MIMEDefang | Milter socket + spool — persist to survive container restarts |
/var/spool/MD-Quarantine | Quarantine directory |
/etc/pki/tls/mimedefang | TLS certificates (key.pem + cert.pem) |
For any main.cf directive not covered by an environment variable, create a
plain text file with one key = value per line and bind-mount it:
# extra.cf
message_size_limit = 52428800
smtpd_helo_required = yes
volumes:
- ./extra.cf:/etc/postfix/extra.cf:ro
When building the image yourself (see GitHub):
| ARG | Default | Description |
|---|---|---|
BASE_IMAGE | almalinux:9 | Base OS — any RHEL-compatible image works |
MIMEDEFANG_VER | v3.7 | Git tag to build from |
docker build \
--build-arg MIMEDEFANG_VER=v3.7 \
--target prod \
-t mimedefang/postfix:v3.7 .
# Build the CI image
docker build --target ci -t mimedefang/postfix:ci .
# Run the test suite
docker compose -f docker-compose-postfix.yml --profile ci \
up --build --exit-code-from mimedefang-postfix-ci
The filter is a plain Perl file. A minimal example:
use strict;
use warnings;
sub filter_begin { }
sub filter { return action_accept(); }
sub filter_end { }
1;
Mount it at /etc/mail/mimedefang-filter and restart the container. Full
documentation: mimedefang-filter(5) and the
examples directory
in the source tree.
Content type
Image
Digest
sha256:ec0f13e0f…
Size
257.7 MB
Last updated
3 months ago
docker pull mimedefang/postfix