Tutorial

Postal: self-hosted SMTP platform for agencies

Business Email9 min read7 steps

A client complains that order confirmation emails are disappearing, another sees their invoices landing in spam — and you have no logs to understand what happened. Postfix does its job silently, but that is precisely the problem: it is a blind relay, with no interface, no statistics, no bounce management. Postal changes the equation. It is a complete SMTP platform — multi-user web interface, REST API, bounce webhooks, per-domain statistics and per-server analytics — that you deploy on a single VPS to manage your entire agency client portfolio, without depending on Mailgun, Postmark or SendGrid.

Contents· Why agencies need a proper SMTP platform1/9
  1. 01Why agencies need a proper SMTP platform
  2. 02What Postal brings to your agency
  3. 03Prerequisites: VPS, port 25 and dedicated IPv4
  4. 04Installing Postal on a VPS
  5. 05Configuring a sending domain
  6. 06DMARC: the final piece of deliverability
  7. 07Bounce management and statistics
  8. 08Postal vs SaaS solutions vs Postfix relay
  9. 09An email infrastructure you control

Why agencies need a proper SMTP platform

Running client email delivery with Postfix alone means flying blind. The MTA delivers or rejects, but it won't tell you why a bounce occurred, which campaign degraded a domain's reputation, or which client is consuming the most sending resources.

For an agency managing 10, 20 or 50 client domains, that opacity is a direct operational risk. A single misconfigured client can trigger a blacklisting of the shared IP and penalise the entire portfolio. And when the client calls to report a problem, you have nothing to show them.

Postal solves this by adding a full control layer on top of the SMTP pipeline.

What Postal brings to your agency

  • Multi-server web interface: create an isolated sending server per client or per project, each with its own SMTP credentials and API key.
  • Per-domain statistics: delivery rate, bounces, deliverability and sending volume — per sending domain, per period, exportable.
  • Real-time bounce management: every returned message is recorded, categorised (hard/soft), viewable in the interface and dispatched via webhook to your application.
  • REST API and webhooks: integrate Postal with your CRM, e-commerce platform or invoicing tool — one sending endpoint, events in return.
  • Message queues: sends are queued and traceable through to delivery receipt or final error, with no black box.
  • Client isolation: each Postal server has its own IP pools, its own reputation and its own limits — one client in difficulty does not affect the others.
  • MIT licence: open source, no per-email cost, no third-party vendor dependency.

Prerequisites: VPS, port 25 and dedicated IPv4

Postal v3.3.7 installs via Docker. The official prerequisites are:

Resources: at least 2 vCPU and 4 GB of RAM. For volumes above 50,000 emails per day, 8 GB is recommended. Allow at least 25 GB of SSD storage — message logs can grow quickly depending on your configured retention period.

Operating system: Ubuntu 22.04 or Ubuntu 24.04 LTS with Docker Engine and the Docker Compose plugin.

Database: MariaDB 10.6 or higher. MySQL is explicitly not supported. The innodb_log_file_size parameter must be set to at least 10 times the maximum message size.

Port 25: the critical point. Outbound port 25 must be open for Postal to deliver messages to recipient servers. Many cloud providers block it by default — confirm your VPS has a dedicated IPv4 and that port 25 is unblocked before starting installation.

rDNS: the reverse DNS of your IPv4 must point to your Postal hostname (e.g. postal.your-agency.com). A missing or incorrect PTR record is the leading cause of rejection by major mail providers.

Installing Postal on a VPS

  1. Prepare the server and install Docker

    Log in as root on your Ubuntu 24.04 VPS, update packages, then install Docker Engine and the Compose plugin:

    apt update && apt upgrade -y
    curl -fsSL https://get.docker.com | sh
    docker --version && docker compose version

    Verify that outbound port 25 is open: nc -zv smtp.gmail.com 25. If the connection fails, contact your hosting provider to unblock it.

  2. Configure DNS for your Postal server

    Before bootstrapping, create DNS records for your Postal installation domain (e.g. postal.your-agency.com):

    - A record: postal.your-agency.com → VPS IP
    - rDNS (PTR): configure this in your control panel so your IP resolves back to postal.your-agency.com
    - SPF for the infrastructure domain: v=spf1 ip4:<VPS_IP> ~all

    Wait for DNS propagation (15 to 30 minutes) before proceeding.

  3. Bootstrap the Postal configuration

    Pull the Postal image and run bootstrap to generate configuration files:

    docker pull ghcr.io/postalserver/postal:latest
    mkdir -p /opt/postal/config
    docker run --rm -v /opt/postal/config:/config \
      ghcr.io/postalserver/postal:latest \
      postal bootstrap postal.your-agency.com

    This generates /opt/postal/config/postal.yml and signing.key. Open postal.yml and fill in the MariaDB credentials, notification SMTP and the public URL of your installation.

  4. Start MariaDB and initialise the database

    Launch a dedicated MariaDB container (or use an existing instance), then initialise the Postal schema:

    docker run -d --name postal-mariadb \
      -e MYSQL_ROOT_PASSWORD=<password> \
      -e MYSQL_DATABASE=postal \
      --restart always mariadb:10.11
    
    docker run --rm -v /opt/postal/config:/config \
      --network host \
      ghcr.io/postalserver/postal:latest \
      postal initialize
  5. Create the first admin user

    Create your administrator account to access the web interface:

    docker run --rm -v /opt/postal/config:/config \
      --network host \
      ghcr.io/postalserver/postal:latest \
      postal make-user

    Enter the email address, name and password for the administrator.

  6. Start Postal and configure the reverse proxy

    Launch all Postal services (web, workers, SMTP):

    docker run -d --name postal \
      --restart always \
      --network host \
      -v /opt/postal/config:/config \
      ghcr.io/postalserver/postal:latest \
      postal start

    Postal exposes the web interface on port 5000. Place a reverse proxy (Caddy or nginx) in front to terminate TLS, then access https://postal.your-agency.com.

  7. Create an organisation and first sending server

    In the Postal interface, create an organisation (your agency), then a sending server for your first client. Each server has its own SMTP credentials, its own API key and its own sending domains — it is the client isolation unit.

    Note the SMTP hostname, port (25, 465 or 587) and the generated credentials: these are the settings to hand to the client application or configure in its sending panel.

Configuring a sending domain

In each Postal sending server, add the domains from which your clients will send email. For each domain, Postal automatically generates a 1024-bit RSA key pair and a unique DKIM selector (format postal-XXXXXX._domainkey).

DNS records to publish for each client domain:

SPF — add include:spf.postal.your-agency.com in the apex TXT record:

v=spf1 include:spf.postal.your-agency.com ~all

DKIM — publish the TXT value shown in the interface at the generated subdomain:

postal-XXXXXX._domainkey.client-domain.com  TXT  "v=DKIM1; k=rsa; p=<public key>"

Return Path (recommended) — a CNAME to improve bounce tracking:

psrp.client-domain.com  CNAME  psrp.postal.your-agency.com

Postal checks these records automatically every hour and flags any missing or incorrect record in the interface. The Check my records button triggers an immediate manual check.

DMARC: the final piece of deliverability

With SPF and DKIM in place, add a DMARC policy on each client domain to tell receivers how to handle alignment failures. Start in monitoring mode (p=none) to collect reports without risk of blocking, then progressively harden to p=quarantine and p=reject:

_dmarc.client-domain.com  TXT  "v=DMARC1; p=none; rua=mailto:[email protected]; fo=1"

The rua attribute sends daily aggregate reports to your address — you will see which sources send on your behalf, legitimate or otherwise. Postal itself produces SPF + DKIM aligned emails: on correctly configured domains, DMARC will pass from day one.

Bounce management and statistics

This is the most visible difference between Postal and a bare Postfix relay. In the Messages tab of each sending server, every sent email is tracked with its status: Sent, Delivered, SoftFail, HardFail, Bounced.

When a bounce is detected, Postal:
1. Records the exact rejection reason in the message log (e.g. 550 5.1.1 The email account does not exist)
2. Updates the delivery status in the interface
3. Fires a MessageBounced webhook event to your configured HTTP endpoint

A bounce log visible in the interface looks like:

[2026-10-15 09:14:22] Delivery attempt to mx1.example.com (203.0.113.10:25)
[2026-10-15 09:14:22] << 550 5.1.1 <[email protected]> User unknown
[2026-10-15 09:14:22] Message marked as HardFail (permanent)

Per-domain statistics aggregate, over sliding windows (24 h, 7 d, 30 d): volume sent, delivery rate, bounce rate, spam filter rejection rate. These data let you detect a deliverability issue before the client notices it themselves.

Postal vs SaaS solutions vs Postfix relay

Scroll the table

CriterionPostal (self-hosted)Mailgun / PostmarkSMTP relay Postfix
VisibilityFull interface: per-message log, bounce log, per-domain statisticsSaaS dashboard with 30-day logs (plan dependent)No interface — system logs only
CostVPS + administration time (no per-email cost)Per-send billing (approximately $0.80–$1.20 per 1,000 emails)VPS only (no software cost)
ControlTotal: IP, retention, bounce policy, per-client isolationPartial: policies imposed by provider, shared IPs by defaultFull routing control, zero visibility
Send limitLimited by VPS resources and IP reputation — scalableQuotas per plan, scale-up billedLimited by VPS — no native per-domain quota management

An email infrastructure you control

Postal is the tool agencies look for when they realise Postfix alone is no longer enough to operate a client portfolio. The platform brings the visibility that was missing — structured logs, tracked bounces, per-domain statistics — without the pricing constraints and vendor dependencies of SaaS alternatives.

A VPS with 2 vCPU, 4 GB of RAM and a dedicated IPv4 is sufficient to get started. Unblocked port 25 and a correctly configured rDNS are the two prerequisites that many providers do not fulfil by default — check them before ordering.

The articles Postfix SMTP relay on VPS and SPF, DKIM and DMARC complete this guide to cover deliverability as a whole.

A VPS for your SMTP platform

Postal requires at least 2 vCPU and 4 GB of RAM. Our VPS plans include a dedicated IPv4, root access, configurable rDNS and port 25 unblocked on request — the exact prerequisites for a production Postal installation.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab