Overview

Example domain: example.com
Mail hostname: mail.example.com
Deployment platform: Dokploy
Mail server: Stalwart
Reverse proxy: Dokploy’s built-in Traefik
Initial storage: Local RocksDB in Docker volumes

Self-hosting email is not difficult because of the mail-server container itself. The complexity comes from coordinating several independent systems correctly:

  • Public DNS

  • Reverse DNS

  • SMTP port 25

  • Docker networking

  • TLS certificates

  • SMTP submission

  • IMAP

  • SPF, DKIM, and DMARC

  • Mail-client discovery

  • Backups

  • Certificate renewals

  • Storage and disaster recovery

This guide documents a complete working deployment from an empty server to a functioning custom-domain mail system.

The final installation supports:

  • Receiving email from the internet

  • Sending email to Gmail and other providers

  • Standard mailboxes

  • Aliases

  • Catch-all delivery

  • Apple Mail, Thunderbird, Outlook, and mobile clients

  • IMAP over TLS

  • SMTP submission over TLS

  • SPF, DKIM, and DMARC authentication

  • MTA-STS and TLS reporting

  • Automatic mail-client configuration

  • CalDAV calendars

  • CardDAV contacts

  • Deployment alongside other Dokploy applications

  • Offsite backups and future external storage


1. Architecture overview

The completed architecture looks like this:

                             ┌───────────────────────────┐
                             │      DNS provider         │
                             │                           │
                             │ MX → mail.example.com     │
                             │ A  → VPS public IPv4      │
                             │ SPF, DKIM, DMARC          │
                             │ SRV, MTA-STS, TLS-RPT     │
                             └────────────┬──────────────┘


┌──────────────────────┐       ┌─────────────────────────────────┐
│ Remote mail servers  │ SMTP  │             VPS                 │
│ Gmail, Outlook, etc. ├──────►│                                 │
└──────────────────────┘  :25  │  ┌───────────────────────────┐  │
                               │  │ Stalwart                  │  │
┌──────────────────────┐       │  │                           │  │
│ Mail applications    │ IMAP  │  │ SMTP reception      :25  │  │
│ Apple Mail, etc.     ├──────►│  │ SMTP submission     :465 │  │
└──────────────────────┘  :993 │  │ SMTP STARTTLS       :587 │  │
                               │  │ IMAPS                :993 │  │
┌──────────────────────┐       │  │ Internal HTTP       :8080│  │
│ Browser              │ HTTPS │  └────────────┬──────────────┘  │
│ /admin and /account  ├──────►│               │                 │
└──────────────────────┘       │  ┌────────────▼──────────────┐  │
                               │  │ Dokploy / Traefik :443    │  │
                               │  └───────────────────────────┘  │
                               └─────────────────────────────────┘

There are two different traffic paths.

Web traffic

Browser
→ VPS ports 80/443
→ Dokploy Traefik
→ Stalwart port 8080

This covers:

  • Stalwart administration

  • User account management

  • Autoconfig

  • Autodiscover

  • MTA-STS

  • CalDAV

  • CardDAV

  • JMAP

  • WebDAV

Mail-protocol traffic

Internet SMTP → VPS port 25  → Stalwart port 25
Mail client   → VPS port 465 → Stalwart port 465
Mail client   → VPS port 587 → Stalwart port 587
Mail client   → VPS port 993 → Stalwart port 993

These connections do not pass through the ordinary HTTP reverse proxy.

This allows other Dokploy applications to continue sharing the same VPS:

app1.example.com  → application container
api.example.com   → API container
logs.example.com  → monitoring container
mail.example.com  → Stalwart

Traefik routes web applications based on hostname. Stalwart owns only its dedicated mail ports.


2. Values used throughout this guide

Replace these placeholders with your own values:

Domain:              example.com
Mail hostname:       mail.example.com
VPS IPv4:            203.0.113.10
Primary mailbox:     user@example.com
Administrator URL:   https://mail.example.com/admin
Account portal:      https://mail.example.com/account

Never use example.com literally in a real deployment.

Comments