Business Email10 min read

Hosting Stalwart Mail Server on a VPS: Complete Guide

A single Go binary — SMTP, IMAP, JMAP, CalDAV, CardDAV and WebAdmin — to operate email for multiple client domains from one VPS, without a multi-container Docker stack. For an agency managing ten separate domains, Mailcow demands heavy resources: at least 6 GB of RAM, multiple containers, complex multi-domain configuration. Stalwart Mail Server takes a different approach: one instance, a statically compiled Go binary, and a native multi-tenant engine that isolates domains and mailboxes without duplicating infrastructure. With around 14,000 stars on GitHub and an active stable release (v0.16.18, August 2026), the project has moved past the experimental stage.

Why Stalwart for a multi-domain client fleet

Managing email for multiple clients runs into the same obstacle: every popular solution forces either a separate instance per domain or a shared setup with only partial isolation. Stalwart was built from the ground up for multi-tenancy: a domain is a first-class object in its data model, not a configuration variant. Adding a client means creating a domain through the API or the web interface — no binary swap, no container restart, no risk of data bleed between clients.

For an agency managing 5 to 50 clients, this is the difference between infrastructure that grows linearly (one extra instance per client) and infrastructure that scales flat — one VPS, one instance, N clients.

What Stalwart brings in practice

  • Single binary, no Docker required — one statically compiled Go file, no system dependencies, deployable directly on any Linux distribution.
  • Native multi-tenancy — domains, mailboxes, aliases and quotas managed as objects, with strict data isolation between clients.
  • JMAP (RFC 8620) as a first-class protocol — the modern email synchronisation protocol, alongside classic IMAP4 and POP3.
  • Built-in WebAdmin — HTTPS administration interface on port 8080, no third-party tool to deploy.
  • JMAP API for automation — scriptable domain and account creation, suited to agency client onboarding workflows.
  • Native ACME/Let's Encrypt support — automatic TLS renewal without Certbot or a mandatory reverse proxy.
  • AGPL-3.0 licence — verifiable source code, no proprietary dependency for the community edition.

Prerequisites before installation

Stalwart is significantly lighter than Mailcow. For light usage (1 to 5 domains, a few dozen mailboxes), plan for 1 vCPU and 1 GB of RAM. For a fleet of several dozen active client domains, 2 vCPU and 2 GB of RAM is the recommended configuration — the figure cited in the official documentation for multi-domain use.

On the network side, four inbound ports must be open: 25 (SMTP, MX reception), 465 (SMTPS/submission), 993 (IMAPS) and 443 (HTTPS — WebAdmin and JMAP). Port 4190 is needed for Sieve (server-side filters). Your VPS must have a dedicated IPv4 and a configured rDNS pointing to the server hostname — essential for deliverability. Finally, a domain name with DNS zone access is required to set MX, SPF, DKIM and DMARC records.

Installing Stalwart Mail Server

01

Download the binary

Connect to your VPS via SSH. Download the latest stable release from the official repository:

curl -fsSL https://github.com/stalwartlabs/stalwart/releases/latest/download/stalwart-linux-x86_64.tar.gz | tar -xz -C /usr/local/bin/
chmod +x /usr/local/bin/stalwart

For an ARM server (Ampere, AWS Graviton), replace x86_64 with aarch64.

02

Run the installation wizard

Stalwart includes an interactive wizard that configures data directories, generates initial TLS certificates and creates the first admin account:

sudo stalwart --init

The wizard asks for the server hostname (e.g. mail.your-domain.com), the data path (default /opt/stalwart-mail), TLS mode (ACME recommended) and the admin password. After init, configuration files are placed in /opt/stalwart-mail/etc/.

03

Create the systemd unit

To make Stalwart start automatically, create the service unit:

sudo tee /etc/systemd/system/stalwart-mail.service << 'EOF'
[Unit]
Description=Stalwart Mail Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/stalwart --config /opt/stalwart-mail/etc/config.toml
Restart=on-failure
User=stalwart

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now stalwart-mail

Create the dedicated user first: sudo useradd -r -s /bin/false stalwart && sudo chown -R stalwart /opt/stalwart-mail.

04

Open ports in the firewall

On Ubuntu/Debian with UFW:

sudo ufw allow 25/tcp comment 'SMTP'
sudo ufw allow 465/tcp comment 'SMTPS'
sudo ufw allow 993/tcp comment 'IMAPS'
sudo ufw allow 443/tcp comment 'HTTPS WebAdmin/JMAP'
sudo ufw allow 4190/tcp comment 'Sieve'
sudo ufw reload

If your VPS is behind a cloud firewall (Hetzner, OVH…), replicate these rules in the control panel.

05

Add the first domain via WebAdmin

Open https://mail.your-domain.com:8080 in your browser and log in with the admin account created in step 2. Under Management → Domains, click Add Domain, enter your-domain.com and confirm. Stalwart automatically generates the DNS records to set (MX, SPF, DKIM, DMARC) and displays them in the interface — copy them into your DNS zone.

06

Create mailboxes and verify

Under Management → Accounts, create a user account and assign it to the domain you added. Test reception with:

swaks --to [email protected] --server mail.your-domain.com --port 25

Then test IMAP connectivity from Thunderbird or any mail client — server mail.your-domain.com, port 993, SSL/TLS. For an additional client, repeat step 5 with a new domain: no service restart is needed.

Post-installation configuration

Reverse proxy. If you want to route WebAdmin and JMAP through Nginx (to share port 443 with other services), configure a stream block for mail protocols (25, 465, 993) and an HTTPS server block for /jmap and WebAdmin. Stalwart also accepts direct connections without a proxy — the choice depends on your architecture.

Backup. Stalwart data lives in /opt/stalwart-mail/data/. A daily snapshot of that directory — compressed and transferred off-site — is sufficient for a full restore. With the {{vps.power.name}} plan from ServOrbit, weekly backups are included; enable daily backups for an RPO suited to email workloads.

Additional domains. Each client domain is added through the WebAdmin or the JMAP API. The stalwart binary also exposes a CLI subcommand for batch operations — useful for automated onboarding of new clients.

Hardening: restrict WebAdmin access

WebAdmin listens on 0.0.0.0:8080 by default. In production, restrict access to your admin IPs:

sudo ufw deny 8080
sudo ufw allow from <your-admin-ip> to any port 8080

Also enable two-factor authentication (TOTP) for the admin account under Security → Authentication in WebAdmin. For remote access over an untrusted network, prefer an SSH tunnel rather than exposing port 8080 directly.

Troubleshooting common errors

Literal exceeds the maximum request size of X bytes (IMAP). This message appears when Thunderbird or an IMAP client attempts to upload a large attachment via the APPEND command. Stalwart drops the connection, then the client parses the remaining data stream as IMAP commands. Raise the limit in /opt/stalwart-mail/etc/config.toml at the imap.request.max-size key and restart the service.

DKIM record rejected by registrar. If your DNS provider (Vultr, some registrars) fails to create the DKIM RSA key because it exceeds 255 characters, split it into two quoted segments in the TXT value: "v=DKIM1; k=rsa; p=MIIBIj..." "AQAB...". Stalwart concatenates them on read.

Punycode domain rejected at creation. Versions before v0.16 rejected internationalised domains already encoded as A-labels (e.g. xn--mysite-o2a.com). Enter the domain in Unicode (mysité.com) and let Stalwart handle the conversion.

Service fails to start after upgrade. Check that your configuration file is compatible with the new version: stalwart --check-config /opt/stalwart-mail/etc/config.toml. Configuration schema migrations are documented in the release notes on GitHub.

IMAP connections refused from a mobile client. Verify that the TLS certificate is valid and not expired (openssl s_client -connect mail.your-domain.com:993) and that port 993 is open in both UFW and the VPS network firewall.

Going further

Stalwart covers mail infrastructure — reception, sending and storage. For your emails to land in the inbox rather than spam, SPF, DKIM and DMARC records must be correctly set and tested: see our guide on professional email deliverability.

If your cPanel fleet sends transactional email (order confirmations, alerts) and you want to centralise outbound without moving mailboxes, the Postfix SMTP relay guide covers that complementary architecture. For agencies migrating a client portfolio from Google Workspace or Microsoft 365 to self-hosted servers, the Mailcow article details IMAP migration steps.

A VPS for your multi-client mail server

A `{{vps.power.name}}` VPS (2 vCPU / 2 GB RAM) handles a fleet of several dozen client domains with Stalwart — root access, OS choice, dedicated IPv4 included.

Need help?

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