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

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
    env_file:
      - stalwart.env
    dns:
      - 9.9.9.9
      - 1.1.1.1

and the accompanying stalwart.env:

STALWART_PUBLIC_URL=https://stalwart.staging.example.com

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.
  • 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 dns options was enough to get it running.