Stalwart Mail Server Installation

Stalwart is a modern, all-in-one mail server written in Rust that supports JMAP, IMAP4, and SMTP with a built-in web admin interface and automatic spam filtering. This guide covers deploying Stalwart on Linux, configuring JMAP/IMAP/SMTP, setting up DKIM signing, and using the web admin panel.

Prerequisites

  • Ubuntu 20.04+/Debian 11+ or CentOS 8+/Rocky Linux 8+
  • Minimum 1 GB RAM (2 GB recommended)
  • A domain name with DNS control
  • Ports 25, 80, 443, 587, 465, 993, 8080 accessible
  • Root or sudo access
  • No other mail server running

Installing Stalwart

# Create a dedicated user and directories
useradd -r -s /sbin/nologin stalwart-mail
mkdir -p /opt/stalwart-mail/{data,logs,config}
chown -R stalwart-mail:stalwart-mail /opt/stalwart-mail

# Download and install via the official install script
curl -fsSL https://get.stalw.art/install.sh | \
  sudo bash -s -- --path /opt/stalwart-mail

Alternatively, download the binary manually:

# Get the latest release
VERSION=$(curl -s https://api.github.com/repos/stalwartlabs/mail-server/releases/latest \
  | grep '"tag_name"' | cut -d'"' -f4)

# Download for Linux x86_64
wget "https://github.com/stalwartlabs/mail-server/releases/download/${VERSION}/stalwart-mail-x86_64-unknown-linux-gnu.tar.gz"

tar xzf stalwart-mail-*.tar.gz -C /usr/local/bin/
chmod +x /usr/local/bin/stalwart-mail

# Install with wizard
stalwart-mail --install

Initial Setup Wizard

Run the interactive setup wizard:

sudo stalwart-mail --config /opt/stalwart-mail/config/config.toml --init

The wizard prompts for:

  1. Base directory: /opt/stalwart-mail
  2. Domain: yourdomain.com
  3. Hostname: mail.yourdomain.com
  4. Admin password: Choose a strong password
  5. TLS: Choose Let's Encrypt automatic or provide existing certs

Start as a systemd service:

# The installer creates the service, or create it manually
sudo tee /etc/systemd/system/stalwart-mail.service << 'EOF'
[Unit]
Description=Stalwart Mail Server
After=network.target

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

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now stalwart-mail
sudo systemctl status stalwart-mail

DNS Configuration

Required DNS records:

# A record
mail.yourdomain.com.    IN  A       YOUR_SERVER_IP

# MX record
yourdomain.com.         IN  MX  10  mail.yourdomain.com.

# SPF
yourdomain.com.         IN  TXT     "v=spf1 mx -all"

# DKIM (get value from admin panel after setup)
mail._domainkey.yourdomain.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."

# DMARC
_dmarc.yourdomain.com.  IN  TXT     "v=DMARC1; p=reject; rua=mailto:[email protected]"

# JMAP SRV record (for auto-discovery)
_jmap._tcp.yourdomain.com. IN SRV 0 1 443 mail.yourdomain.com.

Set reverse DNS at your VPS provider to mail.yourdomain.com.

SMTP and DKIM Configuration

Stalwart's configuration is in TOML format. Key SMTP settings:

# /opt/stalwart-mail/config/config.toml

[server.listener."smtp"]
bind = ["0.0.0.0:25"]
protocol = "smtp"
tls.implicit = false

[server.listener."submission"]
bind = ["0.0.0.0:587"]
protocol = "smtp"
tls.implicit = false

[server.listener."submissions"]
bind = ["0.0.0.0:465"]
protocol = "smtp"
tls.implicit = true

[session.rcpt]
relay = [{ if = "authenticated-as", ne = "", then = true }, { else = false }]

[session.ehlo]
reject-non-fqdn = true

Generate and configure DKIM keys:

# Generate DKIM key via admin panel, or manually
openssl genrsa -out /opt/stalwart-mail/config/dkim-private.pem 2048
openssl rsa -in /opt/stalwart-mail/config/dkim-private.pem \
  -pubout -out /opt/stalwart-mail/config/dkim-public.pem

# Extract public key for DNS
openssl rsa -in /opt/stalwart-mail/config/dkim-private.pem -pubout \
  | grep -v "PUBLIC KEY" | tr -d '\n'

Add to config:

[signature."mail.yourdomain.com"]
private-key = "/opt/stalwart-mail/config/dkim-private.pem"
domain = "yourdomain.com"
selector = "mail"
headers = ["From", "To", "Date", "Subject", "Message-ID"]
algorithm = "rsa-sha256"
canonicalization = "relaxed/relaxed"

JMAP and IMAP Configuration

JMAP (JSON Meta Application Protocol) is Stalwart's modern email API:

[server.listener."jmap"]
bind = ["0.0.0.0:443"]
protocol = "http"
tls.implicit = true

[jmap.session.timeout]
authenticated = "30m"
anonymous = "1m"

# JMAP push notifications
[jmap.push]
max-total = 100
throttle = "1s"

IMAP configuration for legacy clients:

[server.listener."imap"]
bind = ["0.0.0.0:143"]
protocol = "imap"
tls.implicit = false

[server.listener."imaps"]
bind = ["0.0.0.0:993"]
protocol = "imap"
tls.implicit = true

[imap.auth]
max-failures = 3
allow-plain-text = false

Spam Filtering

Stalwart includes built-in spam filtering using Rspamd or its own Sieve-based filters:

[spam-filter]
enable = true
# Set the spam threshold
threshold.discard = 15
threshold.reject = 12
threshold.spam = 5

# Bayes learning
[spam-filter.bayes]
enable = true
min-learns = 200

# DNSBL checks
[spam-filter.dnsbl]
enable = true

Train the Bayes filter:

# Mark messages as spam (via admin panel or IMAP commands)
# Or feed a corpus of known spam:
stalwart-mail spam-learn --ham /path/to/ham/
stalwart-mail spam-learn --spam /path/to/spam/

Web Admin Interface

Access the admin panel at https://mail.yourdomain.com:8080/admin or https://mail.yourdomain.com/admin depending on your setup.

Default credentials:

  • Username: admin
  • Password: Set during the wizard (or check the install output)

From the admin panel you can:

  • Add/manage domains and accounts
  • View DKIM keys and DNS status
  • Monitor the mail queue
  • Configure spam filter settings
  • Run diagnostics

Manage accounts via CLI:

# Create an account
stalwart-mail manage account create \
  --name alice \
  --email [email protected] \
  --password StrongPassword123

# List accounts
stalwart-mail manage account list

# Add an alias
stalwart-mail manage alias create [email protected] [email protected]

Migrating from Legacy Servers

Migrate from Postfix/Dovecot or other servers:

# Export mail from existing Dovecot server (on old server)
# Using imapsync
apt install -y imapsync

imapsync \
  --host1 old-mail.yourdomain.com \
  --user1 [email protected] \
  --password1 OldPassword \
  --host2 mail.yourdomain.com \
  --user2 [email protected] \
  --password2 NewPassword \
  --ssl1 --ssl2

# Import from Maildir format directly
stalwart-mail import maildir \
  --path /var/mail/alice/Maildir \
  --account [email protected]

Troubleshooting

SMTP connection refused on port 25:

# Check if the port is listening
ss -tlnp | grep ':25'

# Many VPS providers block port 25 by default
# Check provider firewall and request unblocking if needed

TLS certificate issues:

# Check certificate status
journalctl -u stalwart-mail | grep -i cert

# Verify domain A record resolves correctly (required for Let's Encrypt)
dig mail.yourdomain.com

# Force certificate renewal via admin panel or:
stalwart-mail --acme-renew

Messages rejected with "relay access denied":

Ensure SMTP authentication is configured for submission (port 587/465). Check that clients authenticate before sending.

JMAP clients not connecting:

# Verify JMAP endpoint is accessible
curl -v https://mail.yourdomain.com/.well-known/jmap

# Check logs
journalctl -u stalwart-mail -f | grep jmap

Conclusion

Stalwart delivers a modern, high-performance mail server that supports both classic IMAP/SMTP clients and the new JMAP protocol, all in a single Rust binary with low resource overhead. Its built-in spam filtering, web admin interface, and automated TLS make it a compelling option for teams migrating away from complex Postfix/Dovecot stacks. Configure DKIM, SPF, and DMARC immediately after setup to ensure good email deliverability.