Our container image

This page contains information about how Postal actually is packaged and run within a container.

Where's the container?

Postal is packaged and hosted at

The latest tag will always track the main branch within the repository and therefore will have the latest copy of the application. It is not recommended to use this tag in production because you may start using it at any time without noticing.

Each version of Postal will also be tagged, for example, 3.0.0. We always recommend using a version tag in production. To upgrade, you simply need to start using the newer version of the container and be sure to run the upgrade command. You can view all the tags which exist on GitHub and in our CHANGELOG.

What processes need to run?

There are 3 processes that need to be running for a successful Postal installation. All processes are run within the same image ( The table below identifies the processes.

The web server

  • Command: postal web-server
  • Ports: 5000

This is the main web server that handles all web traffic for Postal's admin interface and open/click tracking requests. By default, it listens on port 5000 but this can be configured in the postal.yml file by changing the web_server.default_port option or setting the PORT environment variable.

You can run multiple web servers and load balance between them to add additional capacity for web requests.

The SMTP server

  • Command: postal smtp-server
  • Ports: 25
  • Capabilities required: NET_BIND_SERVICE

This is the main SMTP server for receiving messages from clients and other MTAs. As with the web server, you can configure this to run on any port by changing the smtp_server.default_port option in the postal.yml config file or setting the PORT environment variable.

You can run multiple SMTP servers and load balance between them to add additional capacity for SMTP connections.

The worker(s)

  • Command: postal worker

This runs a worker which will receive jobs from the message queue. Essentially, this handles processing all incoming and outgoing e-mail. If you're needing to process lots of e-mails, you may wish to run more than one of these. You can run as many of these as you wish.


The image expects all configuration to be mounted at /config. At a minimum, this directory must contain a postal.yml and a signing.key. You can see a minimal example postal.yml in the installation tool repository. For a full example, see here.

The signing.key can be generated using the following command:

openssl genrsa -out path/to/signing.key 2018


If you wish to utilise IP pools, you will need to run Postal using host networking. This is because Postal will need to be able to determine which physical IPs are available to it and be able to send and receive traffic on those IPs.

If you are not using IP pools, there is no need to use host networking and you can expose the ports listed above as appropriate.

Waiting for services

The container's entrypoint supports waiting for external services to be ready before starting the underlying process. To use this you need to set the WAIT_FOR_TARGETS environment variable with a list of services and ports. For example, mariadb:3306, replacing mariadb with the hostname or IP of your MariaDB server. You can specify multiple endpoint by separating them with a space.

The default maximum time to wait is 30 seconds, you can override this using the WAIT_FOR_TIMEOUT environment variable.