Stalwart is a collaboration server with a self-hostable free tier. it provides not only email, but also calendar, contact, and filesharing support.
See also
- Homepage: https://stalw.art
- Documentation: https://stalw.art/docs/install/
- Free-tier code: https://github.com/stalwartlabs/stalwart
- Installation validity tests: Email Testers and Validators
Docker installation
For docker compose:
services:
stalwart:
container_name: stalwart
image: stalwartlabs/stalwart:latest
restart: unless-stopped
ports:
- "25:25" # SMTP
#- 110:110 # POP3
#- 443:443 # HTTPS
- 465:465 # SMTPS
- 587:587 # SMTP submission (STARTTLS)
#- 143:143 # IMAP4
- 993:993 # IMAPS
#- 995:995 # POP3S
#- 4190:4190 # ManageSieve
#- 8080:8080 # HTTPS admin interface
volumes:
- ./config:/etc/stalwart
- /opt/docker/stalwart/data:/var/lib/stalwart
- /opt/docker/stalwart/logs:/var/log/stalwart
env_file:
- stalwart.env
dns:
- 9.9.9.9
- 1.1.1.1and the accompanying stalwart.env:
STALWART_PUBLIC_URL=https://stalwart.staging.example.com
Make sure you set all the mounts’ to be owned by UID 2000.
Docker Compose notes
- I’ve commented out the ports that I don’t use here, but listed them anyways for reference.
- Port 8080 is the admin interface and, if you are able to, should be made available only to trusted networks
- Port 443 is public-facing HTTPS for web administration, JMAP, OAuth, certificate provisioning, and a few others. If you don’t map it here, you will need to set up a reverse-proxy to it.
- If you use Caddy to do this, see Disable upstream TLS verification; it doesn’t like Stalwart’s self-signed cert.
- I had problems with Stalwart being unable to do DNS queries when starting up. I’m not sure why (haven’t had this problem with other similarly-defined compose services on this machine, nor could I find any references to it online), but specifying the
dnsoptions was enough to get it running.
Authentication
See Authentik & Stalwart.
Troubleshooting
Stalwart’s docker container doesn’t make very much noise when something goes wrong; the instinctive approach of sudo docker logs stalwart --tail=20 often just returns total silence.
Instead, you can try:
- Checking the log file in the
/opt/docker/stalwart/logsfolder on the host (or wherever else you mapped/var/log/stalwartto through docker).- This log is colorized by defailt —
cat/tailare probably better ways to read it, as your console will reapply the formatting (lessorvimwill not, and you’ll have to read through escape codes)
- This log is colorized by defailt —
- Triggering a config reload via the admin panel ⇒ Management ⇒ Actions ⇒ Reload ⇒ Server Settings. This will sometimes spit out an error message if it fails.
- Checking failed tasks via the admin panel ⇒ Management ⇒ Tasks ⇒ Failed. Select a failed task, and at the bottom of the page, inspect the Failure Reason.