Docker Compose configuration for self-hosting Shroud.email.
Please read our deployment documentation on our website.
If you want to get up and running with Shroud.email quickly, and don't want to maintain your own mailserver, you can sign up for our hosted version here.
Copy haraka/haraka_config/config/me.example to haraka/haraka_config/config/me and set your mail hostname.
Caddy defaults to HTTP-01 ACME (port 80), which works behind no other reverse proxy. If your setup needs DNS-01 (e.g. you can't open port 80, or you want wildcard certs), opt in to the Bunny.net DNS challenge:
- Set
BUNNY_API_KEYin.envto your Bunny.net account API key. - Set
CADDYFILE_PATH=./caddy/Caddyfile.bunnyin.env. docker compose up -d --build caddy.
The Caddy binary is built locally (see caddy/Dockerfile) with both the
caddy-permissive-file-storage and caddy-dns/bunny modules. Self-hosters who
leave the defaults get HTTP-01 and never need a Bunny key.
The committed docker-compose.yaml tracks the stable image. If you'd rather
run the latest :edge build (rebuilt on every push to main) and have it
auto-update, copy the example override and bring the stack up:
cp docker-compose.override.example.yaml docker-compose.override.yaml
docker compose up -d
This points the web service at :edge and adds Watchtower,
which polls every 5 minutes and auto-recreates web (and only web) when a new
image is published.
The compose file includes a Cap self-hosted CAPTCHA
instance. It is opt-in at the application level: the
services run by default, but the widget is not rendered and verification
is not performed until you set all three CAP_* variables on the web
service.
Public ingress required.
CAP_INSTANCE_URLmust be a URL a user's browser can reach over HTTPS.
-
Generate an admin key and set
CAP_ADMIN_KEYin.env:openssl rand -hex 32
-
Start the services:
docker compose up -d cap valkey
-
Create a site key. Cap authenticates with a session token issued by logging in with the
ADMIN_KEY. Create asiteKeyandsecretKey` in the Cap UI. -
Set
CAP_INSTANCE_URL,CAP_SITE_KEY, andCAP_SECRET_KEYin.env, then restartweb:docker compose restart web