diff --git a/README.md b/README.md index a77688a..524184c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,22 @@ Please read our [deployment documentation](https://shroud.email/docs/deployment/ If you just want to get up and running with Shroud.email quickly, you can sign up for our hosted version [here](https://app.shroud.email/users/register). +Copy `haraka/haraka_config/config/me.example` to `haraka/haraka_config/config/me` and set your mail hostname. + +## TLS via Bunny DNS-01 (optional) + +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: + +1. Set `BUNNY_API_KEY` in `.env` to your Bunny.net account API key. +2. Set `CADDYFILE_PATH=./caddy/Caddyfile.bunny` in `.env`. +3. `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. + ## Living on the edge The committed `docker-compose.yaml` tracks the stable `:1` image. If you'd rather diff --git a/caddy/Caddyfile.bunny b/caddy/Caddyfile.bunny new file mode 100644 index 0000000..ab5b53d --- /dev/null +++ b/caddy/Caddyfile.bunny @@ -0,0 +1,21 @@ +{ + # Global options + storage permissive_file_storage { + root "/data" + } + + email {$ADMIN_EMAIL} +} + +{$APP_DOMAIN} { + reverse_proxy web:8080 + tls { + dns bunny {env.BUNNY_API_KEY} + } +} + +{$EMAIL_DOMAIN} { + tls { + issuer acme + } +} diff --git a/caddy/Dockerfile b/caddy/Dockerfile new file mode 100644 index 0000000..9ee4ac8 --- /dev/null +++ b/caddy/Dockerfile @@ -0,0 +1,14 @@ +# Compile Caddy with custom modules. +# - caddy-permissive-file-storage: world-readable certs so the cron +# sidecar can bundle them for Haraka (the whole reason this fork exists). +# - caddy-dns/bunny: DNS-01 ACME via Bunny.net, opt-in via Caddyfile.bunny. +FROM caddy:2.10-builder AS builder + +RUN xcaddy build v2.10.0 \ + --with github.com/Shroud-email/caddy-permissive-file-storage@main \ + --with github.com/caddy-dns/bunny@v1.2.0 + +# Production image +FROM caddy:2.10-alpine + +COPY --from=builder /usr/bin/caddy /usr/bin/caddy diff --git a/docker-compose.override.example.yaml b/docker-compose.override.example.yaml index ceca03b..bc83543 100644 --- a/docker-compose.override.example.yaml +++ b/docker-compose.override.example.yaml @@ -22,3 +22,4 @@ services: - WATCHTOWER_LABEL_ENABLE=true # ONLY update opted-in containers — never db - WATCHTOWER_POLL_INTERVAL=300 # poll GHCR every 5 min - WATCHTOWER_CLEANUP=true # delete old images after updating + - DOCKER_API_VERSION=1.44 # watchtower 1.7.1's SDK defaults to 1.25, too old for Docker Engine 28+ diff --git a/docker-compose.yaml b/docker-compose.yaml index ce4bb65..3810cb1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -74,20 +74,23 @@ services: - S3_HOST=${S3_HOST} - LOOPS_API_KEY=${LOOPS_API_KEY} - LOOPS_ACTIVE_USERS_LIST_ID=${LOOPS_ACTIVE_USERS_LIST_ID} + - CHATWOOT_MAC_TOKEN=${CHATWOOT_MAC_TOKEN} + - CHATWOOT_BASE_URL=${CHATWOOT_BASE_URL} caddy: - image: ghcr.io/shroud-email/caddy-permissive-file-storage:main + build: ./caddy restart: unless-stopped environment: - ADMIN_EMAIL=${ADMIN_EMAIL} - APP_DOMAIN=${APP_DOMAIN} - EMAIL_DOMAIN=${EMAIL_DOMAIN} + - BUNNY_API_KEY=${BUNNY_API_KEY} ports: - "80:80" - "443:443" volumes: - caddy_data:/data - - ./caddy/Caddyfile:/etc/caddy/Caddyfile + - ${CADDYFILE_PATH:-./caddy/Caddyfile}:/etc/caddy/Caddyfile cron: build: ./cron diff --git a/example.env b/example.env index f4c06fc..5ed78d9 100644 --- a/example.env +++ b/example.env @@ -30,6 +30,22 @@ AWS_SECRET_ACCESS_KEY=replace S3_BUCKET=replace S3_HOST=replace +# CHATWOOT_MAC_TOKEN / CHATWOOT_BASE_URL: optional, for Chatwoot support +# auth on the hosted app. Leave blank if unused. +CHATWOOT_MAC_TOKEN= +CHATWOOT_BASE_URL= + +# BUNNY_API_KEY: optional. Bunny.net API key for DNS-01 ACME TLS issuance in +# Caddy. Only used if you opt in by setting CADDYFILE_PATH to +# ./caddy/Caddyfile.bunny below. Leave blank to keep the default HTTP-01. +BUNNY_API_KEY= + +# CADDYFILE_PATH: optional. Path to the Caddyfile to mount into the caddy +# container. Defaults to ./caddy/Caddyfile (HTTP-01). Set to +# ./caddy/Caddyfile.bunny to use DNS-01 via Bunny (requires BUNNY_API_KEY). +# Self-hosters can leave the default. +CADDYFILE_PATH=./caddy/Caddyfile + ## You can leave the defaults for the remaining options. DB_USER=postgres diff --git a/haraka/haraka_config/config/me b/haraka/haraka_config/config/me deleted file mode 100644 index fb63837..0000000 --- a/haraka/haraka_config/config/me +++ /dev/null @@ -1 +0,0 @@ -Shroud.email \ No newline at end of file diff --git a/haraka/haraka_config/config/me.example b/haraka/haraka_config/config/me.example new file mode 100644 index 0000000..de54ac6 --- /dev/null +++ b/haraka/haraka_config/config/me.example @@ -0,0 +1 @@ +example.com