MailKite
Get your API key
All server guides
Open Source Mail Servers

How to install Postal v3 on a VPS

Install Postal v3 on a dedicated server, configure MariaDB and DNS, start its containers, and verify the web interface before sending.

Reviewed

Postal is a self-hosted email delivery platform. To install it, prepare a dedicated VPS with Docker, Docker Compose, MariaDB, a public hostname, and working DNS, then use Postal’s installation helper to generate configuration, initialize the database, create an administrator, and start the services. This guide follows Postal’s current v3 documentation; your team remains responsible for the host, database, mail reputation, DNS, upgrades, and backups.

Check the server before installing

Postal’s current prerequisites recommend a dedicated server with at least 4 GB RAM, 2 CPU cores, and 25 GB disk. Confirm that your provider permits outbound SMTP on port 25. A blocked port prevents direct delivery regardless of whether the Postal dashboard loads. Postal also calls for Docker Engine, the Docker Compose plugin, Git, curl, jq, and MariaDB 10.6 or later. The Postal documentation says MySQL is not a supported substitute for MariaDB.

Choose a hostname such as postal.mail.example.net and configure its DNS before bootstrap. Reserve an IP address and ask the hosting provider to set its PTR (reverse DNS) record to the sending hostname. Before you commit production traffic, verify that the IP is not already listed on relevant blocklists and confirm your provider’s abuse and port policies.

Postal logo

This walkthrough describes the official installation path; it does not provision a production-ready host. Use the current Postal prerequisites and installation guide for the latest supported commands.

Install prerequisites and the helper

Install Docker Engine and Docker Compose using the instructions for your server operating system. Install the required utilities, then clone Postal’s maintained install helper:

sudo apt-get update
sudo apt-get install -y git curl jq
sudo git clone https://github.com/postalserver/install /opt/postal/install
sudo ln -s /opt/postal/install/bin/postal /usr/local/bin/postal
docker --version
docker compose version
postal --help

The package command above is for Debian/Ubuntu. Use the equivalent package manager on another supported Docker host. If the symlink already exists, inspect it instead of overwriting it. Keep the helper repository and Postal release aligned with Postal’s current upgrade guidance.

Postal needs MariaDB 10.6 or later. The official prerequisite page includes a container example, but its sample password is explicitly a placeholder. Do not copy that password into a real deployment. Store database credentials in a protected configuration file, restrict database access to the host/network Postal needs, and plan database backups before accepting production mail.

Generate and review Postal configuration

Run the bootstrap command with the hostname that resolves to this server:

sudo postal bootstrap postal.mail.example.net

The helper generates Postal configuration, a signing key, and a Caddyfile under /opt/postal/config. Treat the signing key and database credentials as secrets. Restrict file permissions and keep the configuration directory out of public web roots and source control.

Review postal.yml and set the database connection values for your MariaDB service. Follow the current configuration reference and DNS configuration guide; do not paste a configuration from an older tutorial without checking its version. The installation documentation notes that paths inside the container generally use /config, even when the host files live under /opt/postal/config.

Initialize and start Postal

Once database connectivity and configuration are correct, initialize the schema, create the first administrator, and start Postal:

sudo postal initialize
sudo postal make-user
sudo postal start
sudo postal status

Use the administrator creation prompts to set a real account and a strong password. Postal runs several containers for its web, SMTP, and background-worker functions. postal status reports service state; it does not prove that public DNS, TLS, SMTP delivery, or inbound routing works.

The documented installation path uses Caddy for HTTPS termination. Review the generated Caddyfile and the provider firewall before starting the proxy. Allow only the public ports required for your chosen services, keep MariaDB private, and verify that the hostname resolves to this server before expecting automatic certificate issuance.

Add a sending domain and verify it

Sign in to Postal, create an organization and a virtual mail server, then add the domain you intend to send from. Postal displays the DNS records required for that domain. Publish the exact values it provides for SPF, DKIM, return path, and any other displayed records. DNS values differ by installation; never copy a record from this example or another server.

Wait for DNS propagation, then use Postal’s domain status and a controlled test message to check the setup. Begin with a recipient on a domain you control. Inspect the message result in Postal and check the receiving mailbox, spam folder, and headers. A successful API response means Postal accepted the request; it is not proof of inbox placement.

Production checks before sending real traffic

  • Confirm the dashboard works over HTTPS and the certificate renews.
  • Confirm outbound port 25 is open and the server’s PTR matches its mail hostname.
  • Verify the sending domain’s SPF and DKIM status in Postal and check DMARC alignment for your message stream.
  • Verify Postal workers and MariaDB recover after a host restart.
  • Test database and configuration backups by restoring them to a separate environment.
  • Set up monitoring for disk space, database growth, queue health, delivery errors, and blocklist status.
  • Read Postal’s upgrade notes before pinning or upgrading an image/helper version.

Postal gives you control of the delivery platform, but also makes you the operator of its host, DNS, IP reputation, database, backups, and upgrades. If your application only needs to receive parsed messages as webhooks and send replies, MailKite is a managed alternative to operating this stack. See receive inbound email with Postal and Postal for AI agents.

Sources