Why a self-hosted email server on VPS in 2026
Major email providers — Gmail and Outlook foremost — have tightened their authentication rules. Gmail activated strict rejection of non-compliant senders in November 2025; Microsoft Outlook followed in May 2025 for volumes exceeding 5,000 messages per day. An email sent without properly configured SPF, DKIM and DMARC now ends up in spam or bounces.
For agencies and developers managing multiple client domains, a self-hosted email server on a VPS offers a concrete advantage: centralised infrastructure, controlled IP reputation, and full control over DNS authentication records. The cost of a degraded IP reputation — weeks of warm-up, or even a blacklist — justifies investing in a rigorous configuration from the very first send.
What Stalwart brings compared to a classic stack
- Single binary: SMTP, IMAP4, POP3, JMAP, ManageSieve and WebAdmin in a single process — no multi-container Docker Compose to orchestrate.
- Written in Rust: memory safety by design, low RAM footprint, fast startup.
- SPF, DKIM and DMARC built in: inbound verification and outbound signing configurable from the WebAdmin interface, without third-party plugins.
- JMAP: modern protocol that reduces client latency compared to IMAP alone — supported natively by Stalwart.
- AGPL-3.0: auditable code, no dependency on a proprietary cloud service.
- Integrated WebAdmin: manage domains, accounts, filtering rules and DMARC reports from a browser.
Prerequisites before you start
Stalwart runs on any 64-bit Linux VPS. For stable production use, plan for at least 2 vCPU and 2 GB of RAM — the binary itself is lightweight, but SMTP queue management and IMAP indexing consume memory under load.
Two blocking points to check before installation:
Port 25 must be open outbound. Many hosting providers block this port on entry-level VPS plans to limit spam. Verify with your provider that outbound port 25 is unblocked — without it, Stalwart can receive mail but cannot send to other servers.
The VPS IP must have a correct PTR (reverse DNS record). A missing or inconsistent PTR is one of the primary causes of rejection by major email providers. Most VPS hosting providers allow you to set this PTR from their control panel.
Prerequisites checklist
- 64-bit Linux VPS (Debian 12 or Ubuntu 22.04 recommended), minimum 2 vCPU / 2 GB RAM.
- Dedicated IP — never a shared IP for a production email server.
- PTR DNS configured on the VPS IP: must match the mail server hostname.
- Outbound port 25 unblocked by the hosting provider (verify before ordering).
- Ports 465 (SMTPS), 587 (submission), 993 (IMAPS) and 143 (IMAP) open in the firewall.
- A domain name with access to DNS record management (adding TXT records for SPF, DKIM, DMARC).
- A valid TLS certificate — Let's Encrypt via ACME is natively supported by Stalwart.
Installing Stalwart on a VPS
Stalwart provides an official installation script that downloads the precompiled binary, creates a dedicated system user, installs a systemd service and guides the initial configuration in interactive mode.
Step-by-step deployment
Download and run the installation script
Connect to the VPS as root or with sudo, then run the official script:
curl -fsSL https://get.stalw.art/install.sh | sudo bashThe script detects the architecture, downloads the binary for the latest stable release (v0.16.19 at the time of writing), creates the stalwart-mail user, installs the binary to /usr/local/bin/stalwart-mail and generates the initial configuration in /etc/stalwart/.
Configure the domain and SMTP settings
The script launches an interactive assistant. Enter the primary domain name (mail.yourdomain.com), the sending domain and the mailbox storage path. The configuration is written in TOML to /etc/stalwart/config.toml.
To enable Let's Encrypt, make sure port 443 is accessible and that the DNS record mail.yourdomain.com points to the VPS IP before running the script.
Start the service and check the logs
sudo systemctl enable --now stalwart-mail
sudo systemctl status stalwart-mail
journalctl -u stalwart-mail -fThe service listens on the configured ports. The logs indicate whether the TLS certificate was obtained and whether the SMTP and IMAP sockets are active.
Configure SPF, DKIM and DMARC in DNS
Log in to the WebAdmin (port 8080 by default, to be protected behind a reverse proxy or IP allowlist) and navigate to Management → Domains.
Stalwart generates the DKIM key and displays the DNS records to add. Publish in the DNS manager:
# SPF — authorise the VPS to send for the domain
yourdomain.com. TXT "v=spf1 mx a:mail.yourdomain.com ~all"
# DKIM — public key generated by Stalwart (value shown in WebAdmin)
default._domainkey.yourdomain.com. TXT "v=DKIM1; k=rsa; p=<public key>"
# DMARC — rejection policy with report address
_dmarc.yourdomain.com. TXT "v=DMARC1; p=reject; rua=mailto:[email protected]"Start with p=none (monitoring mode) for 48 to 72 hours, analyse the aggregate reports, then move to p=quarantine and then p=reject.
Create the first accounts and test sending
In the WebAdmin, create a domain and its associated user accounts. Test sending with swaks from the VPS:
swaks --to [email protected] --from [email protected] \
--server mail.yourdomain.com --port 587 \
--auth LOGIN --auth-user [email protected]Check the received message and its Authentication-Results header — it should show spf=pass, dkim=pass and dmarc=pass.
Protect the WebAdmin and harden the firewall
The WebAdmin must not be publicly exposed. Two options: restrict it to a management IP in the Stalwart configuration, or put it behind an nginx reverse proxy with basic authentication.
On the firewall side, only allow strictly necessary ports:
# Example with ufw
ufw allow 25/tcp # Inbound SMTP
ufw allow 465/tcp # SMTPS
ufw allow 587/tcp # Submission
ufw allow 993/tcp # IMAPS
ufw allow 143/tcp # IMAP (if required)
ufw deny 8080/tcp # WebAdmin — restricted access, not publicRefer to the Linux VPS hardening article for the complete firewall configuration and SSH key management.
IP reputation: the most overlooked factor
A technically perfect installation is not enough if the VPS IP is already listed in a negative reputation database (Spamhaus, Barracuda, SORBS). Before going live, check the IP on MXToolbox Blacklists and Spamhaus Checker. If the IP is listed, open a delisting request with each database — a process that takes between 24 hours and two weeks depending on the list. Requesting a fresh IP from the hosting provider is sometimes faster.
Stalwart vs Mailcow: two approaches to self-hosted email
| Criterion | Stalwart Mail Server | Mailcow |
|---|---|---|
| Architecture | Single Rust binary (one process) | Multi-container Docker stack (Postfix, Dovecot, Rspamd, SOGo...) |
| Protocols | SMTP, IMAP4, POP3, JMAP, ManageSieve, CalDAV, CardDAV | SMTP, IMAP4, POP3, ManageSieve, CalDAV, CardDAV |
| Recommended minimum RAM | 2 GB in production | 4 to 6 GB recommended (multiple containers) |
| SPF/DKIM/DMARC | Built into the binary natively | Via Rspamd and OpenDKIM (separate configuration) |
| Admin interface | Integrated WebAdmin (HTTP, REST API) | SOGo + dedicated Mailcow interface |
| Licence | AGPL-3.0 | MIT (but dependencies under various licences) |
| Maturity | Stable, v0.16.x, pre-1.0 | Mature, deployed in production since 2016 |
Common pitfalls to avoid
Missing or inconsistent PTR. This is the most frequent cause of silent rejection by Gmail and Outlook. The PTR must resolve to the hostname used in the SMTP EHLO, which must itself match the sending domain. Check with dig -x <VPS-IP>.
Port 25 blocked by the hosting provider. Some VPS providers block outbound port 25 by default to contain spam. Stalwart can still receive mail, but sending to external servers fails. Checking beforehand avoids discovering this block after installation.
Moving to p=reject on DMARC too quickly. A restrictive DMARC policy applied without a prior monitoring period can block legitimate flows (newsletters, contact forms) if SPF or DKIM does not cover all sending paths. The first 48 to 72 hours in p=none with aggregate reports are essential.
Neglecting IP warm-up. A fresh IP that suddenly sends hundreds of messages per day is flagged as suspicious by spam filters. Gradually increase volume over one to two weeks, starting with the most engaged recipients.
Updates and maintenance
Stalwart publishes regular updates on its GitHub repository. v0.16.19 (August 2026) is the current stable version — the project targets v1.0 after finalising the database schema and performance optimisations.
To update the binary:
sudo systemctl stop stalwart-mail
sudo curl -fsSL https://get.stalw.art/install.sh | sudo bash
sudo systemctl start stalwart-mailConfiguration files in /etc/stalwart/ and data in the storage directory are not overwritten by the update script. Keep a backup of your DKIM keys before any operation — losing the private DKIM key forces DNS record rotation and a propagation period.
Follow releases at github.com/stalwartlabs/stalwart/releases to be notified of security patches.