Webmail for the Stalwart server in your home lab.

Run Bulwark as one container next to Stalwart on a NAS, a VM or a 64-bit ARM board, or put Bulwark Lite on a web server you already run and skip the Node process. It works for one person, a family or a club.

One inbox showing mail from two accounts and a shared mailbox togetherOne inbox showing mail from two accounts and a shared mailbox together

Bulwark is the client for the Stalwart server you already run.

Stalwart handles SMTP, storage, spam filtering and the accounts. Bulwark talks JMAP to it from the browser and puts mail, calendar, contacts and files in one window.

Stalwart and Bulwark in one Compose file.

The images are built for amd64 and arm64; a Raspberry Pi needs a 64-bit OS. On the project's amd64 test VM the container used about 70 MiB of memory at idle, signed out. Put Caddy, nginx or Traefik in front for HTTPS, and drop the ports the two containers publish once it's there; Run Bulwark at home shows that layout.

Compose with Stalwart
services:
  stalwart:
    image: stalwartlabs/stalwart:v1.0
    ports: ["443:443", "25:25", "465:465", "993:993", "8080:8080"]
    volumes:
      - stalwart-etc:/etc/stalwart
      - stalwart-data:/var/lib/stalwart
    restart: unless-stopped

  bulwark:
    image: ghcr.io/bulwarkmail/webmail:latest
    ports: ["3000:3000"]
    environment:
      JMAP_SERVER_URL: https://mail.example.com
    volumes:
      - bulwark-data:/app/data
    depends_on: [stalwart]
    restart: unless-stopped

volumes:
  stalwart-etc:
  stalwart-data:
  bulwark-data:

Bulwark Lite is a folder of static files.

Serve it from any web server, run the 23 MB nginx image, or let Stalwart serve it as an application. Lite leaves out the admin console, plugins and web push. Its nginx image used about 8 MiB at idle on the same VM.

Static hosting
Bulwark Lite's inbox, served as static files under /webmailBulwark Lite's inbox, served as static files under /webmail

Every account in one window.

Sign in to your own mailbox and the family's at once and switch between them. An admin can allow one merged inbox across all of them.

Multiple accounts
The account switcher open, with two signed-in accountsThe account switcher open, with two signed-in accounts

Push to the phone without opening a port for it.

Stalwart sends push to the Bulwark relay over HTTPS, and the relay wakes the phone, so push needs no inbound connection. Reading mail away from home still needs Stalwart and Bulwark reachable, over HTTPS or a VPN. On Android without Google services, the app can push through UnifiedPush with a distributor such as ntfy, through the hosted relay or one you run. A relay of your own is pre-1.0, built from source, and needs a public HTTPS address. The phone app is a beta.

Mobile apps and push
Notification settings with the push relay chosenNotification settings with the push relay chosen

Plugins and themes, and your own.

The admin console installs plugins and themes from the extension directory, such as Paperless-ngx, Nextcloud or a Thunderbird-like theme. A plugin of your own is a manifest and some JavaScript, a theme a manifest and CSS, and the guides cover both.

Plugins
The admin console's marketplace listing plugins and themes from the extension directoryThe admin console's marketplace listing plugins and themes from the extension directory

What Bulwark contacts, and the switch that stops it.

Usage stats are off until you turn them on. Out of the box, Bulwark does check for new releases once an hour, loads sender icons, and uses the project's push relay and extension directory. Set NO_THIRD_PARTY_TRAFFIC=true, or turn on the same switch in the admin console, and all of that stops.

Third-party traffic

What each part needs.

FeatureNeeds
Lite on a separate hostThe Permissive CORS policy in Stalwart, unless Stalwart serves Lite
More than five accounts in one browserHTTPS (HTTP/2) between the browser and Bulwark
Installing as an appHTTPS
Web push in the browserHTTPS and the full edition
Push to the phoneThe beta app, and Stalwart reaching the relay over public HTTPS
UnifiedPushAndroid and a distributor app such as ntfy
PluginsThe full edition; an admin turns them on