Stalwart is an open source mail and collaboration server written in Rust. A single binary provides SMTP, IMAP, POP3, JMAP, ManageSieve, built-in spam filtering, DKIM signing and a web administration interface, with no separate Postfix, Dovecot or Rspamd to maintain. In this tutorial you will install Stalwart on Ubuntu 24.04 with the official installer, secure the admin interface, obtain a TLS certificate, publish the DNS records for your domain, and test sending and receiving mail.

Prerequisites

To follow this tutorial, you will need:

  • A server running Ubuntu 24.04 LTS, for example a CubePath VPS, with at least 1 GB of RAM (2 GB recommended) and no other mail server installed.
  • A non-root user with sudo privileges.
  • A domain name, referred to as your_domain, and access to its DNS zone. The mail host will be mail.your_domain.
  • A static public IPv4 address, referred to as your_server_ip, with reverse DNS (PTR) set to mail.your_domain. Set it from your provider's panel or ask support to do it.
  • Inbound and outbound TCP port 25 allowed by your provider.

Check that nothing is using the mail ports yet:

sudo ss -tlpn | grep -E ':(25|443|465|587|993|8080)\s'

The command should print nothing.

Step 1 - Creating the A record

Stalwart requests its certificate from Let's Encrypt, which needs mail.your_domain to resolve to your server. Create this record in your DNS provider now so it propagates while you install:

TypeNameValue
Amailyour_server_ip

Verify it:

dig +short A mail.your_domain
your_server_ip

You will add the MX, SPF, DKIM and DMARC records in Step 5, using the values Stalwart generates.

Step 2 - Installing Stalwart

Stalwart's supported installation method on Linux is its install script, which downloads the release binary, creates a stalwart system user, writes a default configuration and registers a systemd service. Download the script and read it before running it:

curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh -o stalwart-install.sh
less stalwart-install.sh

Run it:

sudo sh stalwart-install.sh

By default everything is installed under /opt/stalwart, with the configuration file in /opt/stalwart/etc/config.toml and data in /opt/stalwart/data. At the end, the script prints the administrator credentials:

Installation complete! Continue the setup at http://your_server_ip:8080/login

Your administrator account is 'admin' with password 'Xk3...'.

Copy the password now; it is not shown again.

Check that the service is running:

sudo systemctl status stalwart
● stalwart.service - Stalwart Server
     Loaded: loaded (/etc/systemd/system/stalwart.service; enabled; preset: enabled)
     Active: active (running) since ...

Confirm the listeners are open:

sudo ss -tlpn | grep stalwart

You should see Stalwart listening on ports 25, 465, 587, 143, 993, 443 and 8080, among others.

Step 3 - Configuring the firewall and reaching the admin interface

Allow SSH and the ports clients and other mail servers need. Port 80 is used by the Let's Encrypt HTTP challenge in some setups and is harmless to open:

sudo ufw allow OpenSSH
sudo ufw allow 25,80,443,465,587,993/tcp
sudo ufw enable

Port 8080 serves the admin interface over plain HTTP, so do not open it to the internet. Instead, reach it through an SSH tunnel from your own computer:

ssh -L 8080:127.0.0.1:8080 your_user@your_server_ip

With the tunnel open, browse to http://localhost:8080/login and sign in as admin with the password from Step 2. Once HTTPS is working in Step 4, the admin interface is also available at https://mail.your_domain/login.

The first thing to do is change the admin password from the account menu in the web interface.

Step 4 - Setting the hostname and getting a TLS certificate

In the web interface, open Settings and go to the server section:

  1. Under Network, set the server Hostname to mail.your_domain and save. Stalwart uses this name in the SMTP greeting, which must match your PTR record.
  2. Under TLS > ACME Providers, create a provider using the Let's Encrypt production directory, add mail.your_domain to its domains, enter a contact email address, and save.

Apply the changes with Reload configuration, or restart the service:

sudo systemctl restart stalwart

Within a minute or two, Stalwart obtains the certificate through the TLS-ALPN challenge on port 443. Check that the server now presents it:

openssl s_client -connect mail.your_domain:993 -servername mail.your_domain </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject
issuer=C = US, O = Let's Encrypt, CN = R11
subject=CN = mail.your_domain

If you still see a self-signed certificate, look for ACME errors in the log files under /opt/stalwart/logs.

Step 5 - Adding your domain and publishing DNS records

In the web interface, go to Management > Directory > Domains and create your_domain. Stalwart generates DKIM keys for the domain automatically. Open the domain's DNS records view: it lists every record the domain needs, including MX, SPF, the DKIM public keys, DMARC, and autoconfig and SRV entries for clients.

Publish at least these records in your DNS provider, copying the exact values from Stalwart:

TypeNameValue
MX@mail.your_domain (priority 10)
TXT@v=spf1 mx -all
TXTDKIM selector shown by Stalwart, for example 202609r._domainkeyv=DKIM1; k=rsa; h=sha256; p=...
TXT_dmarcv=DMARC1; p=quarantine; rua=mailto:postmaster@your_domain

Stalwart typically publishes both an RSA and an Ed25519 DKIM key; add both. The SRV and autoconfig records are optional but let clients such as Thunderbird configure themselves.

Verify the records:

dig +short MX your_domain
dig +short TXT your_domain
dig +short TXT _dmarc.your_domain

Step 6 - Creating a mail account

Go to Management > Directory > Accounts and create an account:

  • Name (login): alice
  • Email: alice@your_domain
  • Password: a strong password

Save it. Mail clients connect with these settings:

ProtocolServerPortSecurity
IMAPmail.your_domain993SSL/TLS
SMTP submissionmail.your_domain465SSL/TLS
SMTP submissionmail.your_domain587STARTTLS
JMAPhttps://mail.your_domain443HTTPS

Step 7 - Testing SMTP, IMAP and JMAP

Install swaks, a command-line SMTP test tool, and send an authenticated message to an external address you control:

sudo apt install -y swaks
swaks --to your_external_address --from alice@your_domain \
  --server mail.your_domain --port 587 --tls \
  --auth-user alice --auth-password 'alice_password'

The transcript should show with a 250 response for the message, followed by 221 when the connection closes. Check the received message's headers for spf=pass, dkim=pass and dmarc=pass, then reply to it to test inbound delivery.

Check that JMAP discovery works. The session endpoint returns a JSON document describing the account and its capabilities:

curl -s -u 'alice:alice_password' https://mail.your_domain/.well-known/jmap | head -c 300
{"capabilities":{"urn:ietf:params:jmap:core":{...

Finally, configure the account in a mail client with the IMAP settings from Step 6 and confirm the reply arrived.

Step 8 - Reviewing spam filtering

Stalwart's spam filter is enabled by default and combines DNS blocklists, reputation, header and content rules, and a Bayesian classifier. Its settings live under Settings > Spam filter in the web interface, where you can adjust the score thresholds for marking messages as spam or rejecting them. Messages marked as spam are delivered to the user's Junk folder, and users train the Bayes classifier by moving messages into or out of Junk in their mail client.

Keep an eye on the first days of traffic in the logs under /opt/stalwart/logs or the Logs view of the web interface before tightening thresholds.

Updating Stalwart

Download the new release binary from the Stalwart GitHub releases page, or rerun the install script as described in the official upgrade notes for your version, then restart the service:

sudo systemctl restart stalwart

Read the release notes before updating. Some releases change configuration keys or the storage format and include a migration step.

Troubleshooting

Other servers cannot deliver mail to you: from a machine outside your network, run nc -vz mail.your_domain 25. A timeout means port 25 is blocked by a firewall or by your provider.

Clients get a certificate warning: the ACME order has not completed. Confirm mail.your_domain resolves to this server and that port 443 is open, then check the logs in /opt/stalwart/logs for ACME errors.

Sending fails with relay not allowed: the client is not authenticating. Use port 465 or 587 with authentication enabled; port 25 only accepts mail for your own domains.

Outgoing mail lands in spam: verify the PTR record with dig +short -x your_server_ip, and confirm the hostname in Settings is mail.your_domain and the DKIM records match the ones Stalwart shows.

Conclusion

You now have a Stalwart mail server on Ubuntu 24.04 with a Let's Encrypt certificate, SPF, DKIM and DMARC, and a working account reachable over IMAP, SMTP and JMAP. As next steps, configure a backup of /opt/stalwart/data, migrate existing mailboxes from your old server with imapsync, and explore the calendar and contacts support in recent Stalwart releases.