Self-hosted service
bokysan/docker-postfix avatar
bokysan/docker-postfix

docker-postfix: a null relay for outbound mail from containers

Multi architecture simple SMTP server (postfix null relay) host for your Docker and Kubernetes containers. Based on Debian/Ubuntu/Alpine.

812 stars174 forksShellMIT

At a glance

What is it?
docker-postfix runs Postfix inside a container so your applications can send mail through one central relay instead of each one talking to an external SMTP provider. It is a server-side image with no client authentication, and the README says plainly that it is not for managing end user mail.
Who is it for?
Adopt docker-postfix if your applications need a single outbound mail path from containers and you would rather configure one Postfix than give every service SMTP credentials. Do not adopt it to run a mail server for end users, since the README rules that out explicitly, and note that the configuration has no client-side authentication at all, so it must sit on a private network.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A null client, not a mail server

The README draws the line early and in capital letters. This is a server side Postfix image, geared towards emails that need to be sent from your applications, and the configuration does not support username and password login or similar client-side security features. If you want to set up and manage a Postfix installation for end users, this image is not for you. That framing is the whole design. Instead of every container holding credentials for an external mail provider or running its own queue, the containers talk to one relay on the internal network, and the relay handles the actual delivery. The image is called a postfix null relay host, and the practical effect is that your application configuration changes from mail provider credentials to a hostname and a port, and the mail infrastructure moves into one place you can observe and update.

Two run commands and two Helm commands

The TL;DR section gives you the whole deployment surface. Running the container directly:

bash
docker run --rm --name postfix -e "ALLOWED_SENDER_DOMAINS=example.com" -p 1587:587 boky/postfix
# or
docker run --rm --name postfix -e "ALLOWED_SENDER_DOMAINS=example.com" -p 1587:587 ghcr.io/bokysan/postfix

And the Helm path, either from the chart repository or from the OCI registry:

bash
helm repo add bokysan https://bokysan.github.io/docker-postfix/
helm upgrade --install --set persistence.enabled=false --set config.general.ALLOW_EMPTY_SENDER_DOMAINS=yes mail bokysan/mail
# or, using the OCI registry:
helm upgrade --install --set persistence.enabled=false --set config.general.ALLOW_EMPTY_SENDER_DOMAINS=yes mail oci://ghcr.io/bokysan/charts/mail

Two things in there are worth pausing on. The port mapping is 1587 to 587, and after the deployment your applications send to localhost:1587 on Docker. And ALLOW_EMPTY_SENDER_DOMAINS=yes is switched on in the Helm example, which is a deliberate relaxation of the sender-domain check, and is exactly the kind of setting you should think about before copying it into production rather than after.

One image built from three base distributions

The Dockerfile documents its own trade-offs before you pick a tag, which is unusual and helpful. The BASE_IMAGE argument defaults to debian:trixie-slim and can be changed, and the file says it will be. The guidance is that Alpine is for when you are strapped for space, with the caveat that it uses musl libc so unicode support might be an issue. Debian is for the greatest cross-platform compatibility, at the cost of being larger than Alpine. Ubuntu is there for people who want Ubuntu. The image is built automatically with all three as underlying systems, and the top-level repository entries confirm the machinery around that choice, with alpine-versions.sh, build-scripts/ holding the shared install scripts, and build.sh driving the build. The install script ordering in the Dockerfile is deliberate too: Postfix is installed first to get account 101, opendkim second for account 102, and rspamd last so its account ordering stays stable across distributions. Those uids matter because the README has a Security section about UIDs and GIDs.

Configuration is environment variables, and there are many

The table of contents is longer than the feature list, because the surface here is configuration. There are general options and Postfix-specific ones, and the Postfix-specific group is the substantial one. RELAYHOST with RELAYHOST_USERNAME and RELAYHOST_PASSWORD covers relaying to your company's main server. POSTFIX_smtp_tls_security_level sets the TLS posture. There is a whole XOAUTH2 group, XOAUTH2_CLIENT_ID, XOAUTH2_SECRET, XOAUTH2_INITIAL_ACCESS_TOKEN, XOAUTH2_INITIAL_REFRESH_TOKEN and XOAUTH2_TOKEN_ENDPOINT, with subsections for OAuth2 client credentials with Gmail, for obtaining an initial access token, and for debugging XOAuth2 issues. MASQUERADED_DOMAINS rewrites the sender, SMTP_HEADER_CHECKS controls header validation, and POSTFIX_myhostname, POSTFIX_mynetworks and POSTFIX_message_size_limit set the Postfix parameters directly. ALLOWED_SENDER_DOMAINS and ALLOW_EMPTY_SENDER_DOMAINS decide which senders are accepted, AUTOSET_HOSTNAME and AUTOSET_HOSTNAME_SERVICES control hostname behaviour, and SKIP_ROOT_SPOOL_CHOWN and ANONYMIZE_EMAILS handle spool ownership and address rewriting.

Anonymizing email has four filters, and you can write your own

The ANONYMIZE_EMAILS option deserves its own look because it is the feature with the most design in it. The README documents four filters. The default, called smart, is the one you get without configuring anything. There is a paranoid filter, a hash filter, and a noop filter, and each exists because different situations need different degrees of rewriting. The section on writing your own filters means the address rewriting behaviour is extensible rather than fixed, which matters if your requirement is something the four built-ins do not express. Paired with this is MASQUERADED_DOMAINS, which handles the case where the envelope sender has to match a domain your provider will accept, so the two settings together decide what a downstream server sees in both the envelope and the headers.

DKIM signing with a choice of backend

Because the whole point of the image is to deliver mail that is not flagged, signing is central rather than optional. The README documents choosing the DKIM backend with DKIM_BACKEND, and it describes migrating from OpenDKIM to rspamd, which tells you the project has moved its default toward rspamd. You can supply your own DKIM keys, auto-generate the DKIM selectors through the image, change the selector, and override specific settings for either rspamd or OpenDKIM. There is also a section on verifying your DKIM setup, which is the step most people skip and most deliverability problems live in. Both signing stacks are available in the image, since the Dockerfile installs opendkim and rspamd in a fixed order to keep their user ids stable, and the repository topics list dkim and dkim-keys. Without a correct DKIM setup, and without the sending domain configured to allow the relay's address, the README is direct that your emails will most likely be regarded as spam.

Secrets, Helm and Prometheus metrics

The deployment story goes beyond a plain container. There is a Docker Secrets and Kubernetes secrets section, so credentials such as the RELAYHOST password or the OAuth2 secrets can be mounted rather than baked into an environment variable. The Helm chart is published and also listed on ArtifactHub, and it exposes a Metrics section, which means the chart wires up Prometheus metrics for the relay, so queue depth and delivery errors are observable rather than buried in container logs. The chart's persistence setting, which the TL;DR sets to false, controls whether the Postfix queue survives a pod restart, and that choice changes delivery behaviour for mail queued while the pod was down. For extending the image, the README documents using custom init scripts, which is the supported way to add your own configuration without forking the Dockerfile.

Editorial conclusion

Adopt docker-postfix if your applications need a single outbound mail path from containers and you would rather configure one Postfix than give every service SMTP credentials. Do not adopt it to run a mail server for end users, since the README rules that out explicitly, and note that the configuration has no client-side authentication at all, so it must sit on a private network. Before you commit, set ALLOWED_SENDER_DOMAINS, plan for DKIM signing or your mail will be treated as spam, and check whether the Helm chart's persistence setting matches how you want the queue to behave.

Frequently asked questions

What is docker-postfix?

It is a Docker image that runs Postfix as a null relay inside your Docker or Kubernetes environment, so applications can send outgoing email through one central host. It is based on Debian by default, with Ubuntu and Alpine variants, and it is MIT licensed.

How do I run docker-postfix?

With docker run --rm --name postfix -e "ALLOWED_SENDER_DOMAINS=example.com" -p 1587:587 boky/postfix, or the equivalent ghcr.io/bokysan/postfix image. The container is also available as a Helm chart from the bokysan repository or as an OCI chart at oci://ghcr.io/bokysan/charts/mail.

Does docker-postfix support SMTP authentication?

No. The README states this is a server side image geared towards emails sent from your applications, and that the configuration does not support username and password login or similar client-side security features. It is explicitly not intended for managing a Postfix installation for end users.

How do I stop docker-postfix mail being treated as spam?

The README says that if you have not configured your domain to allow sending from the relay's IP, server or name, your emails will most likely be regarded as spam. The image addresses this with DKIM signing, with a selectable backend through DKIM_BACKEND, keys you supply or selectors generated through the image, and a section on verifying the setup.

Official sources

  1. bokysan/docker-postfix on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bokysan-docker-postfix.svg)](https://hysenlabs.com/projects/bokysan-docker-postfix)

Was this useful?