The Caddyfile is reassembled every run, but the WebFinger decision reads BASE_DOMAIN/REDIRECT_URL from .env, and .env was written only on the first run. So enabling WebFinger on a re-run was a silent no-op: the operator answers the apex prompt, and the script prints the green "[+] No BASE_DOMAIN -- pocket-id only" -- contradicting what they just typed -- then pulls, restarts and prints DEPLOYED with exit 0. The failure is invisible at the far end too. Caddy has no site block for the apex, so it never gets a cert for it and discovery fails with a TLS or connection error rather than a 404. Nothing warns; the one contradicting line is a green [+] among docker pull output. Moving the apex had the squid shape: compose reads the shell environment first, so the new value served for that run only, and the documented later `docker compose up -d` fell back to stale .env and reverted it. Record which of the two keys arrived in the environment BEFORE the ":=" defaults, then write those through with a set_env upsert. Only keys actually passed are touched: automations.sh drops a blank optional answer, so "blank" cannot be told apart from "not supplied" and must not be read as "disable". Since that means the prompt cannot retire WebFinger, the enabled path now says so and points at the .env edit that can. Verified: enabling on a re-run lands in .env and appends the block; changing the apex lands and is logged; passing nothing touches nothing; BASE_DOMAIN without REDIRECT_URL still dies rather than half-enabling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pocket-id
Pocket-ID OIDC provider behind Caddy, with an optional Anubis proof-of-work anti-bot gate. The identity provider for the other stacks (headscale, beszel, webfinger).
Required .env values
| Variable | Notes |
|---|---|
POCKETID_DOMAIN |
Public hostname (e.g. id.example.com). |
ACME_EMAIL |
Let's Encrypt registration email. |
ENCRYPTION_KEY |
Generated on first deploy (openssl rand -base64 32). Losing it is unrecoverable. |
ANUBIS_PID_KEY |
Generated on first deploy (openssl rand -hex 32). |
MAXMIND_LICENSE_KEY (audit-log geolocation) is optional. See
.env.example for the full list.
Optional WebFinger: set BASE_DOMAIN (and REDIRECT_URL) to have this
Caddy also serve /.well-known/webfinger at the apex — useful when the base
domain has no other web server. Leave both blank to run pocket-id only and use
the dedicated webfinger deployment instead.
Deploy
From the repo root via the launcher:
./automations.sh # Deploy on this host → deploy: pocket-id
Or build the self-contained artifact and run it on the host:
./build.sh # embeds files into deploy.sh
scp deploy.sh root@host: # copy to the target
ssh root@host 'bash deploy.sh' # interactive
# non-interactive:
# POCKETID_DOMAIN=id.example.com ACME_EMAIL=me@example.com SKIP_PROMPTS=1 bash deploy.sh
Unattended provisioning: cloud-init.yml.
DNS for POCKETID_DOMAIN must resolve to the host and ports 80/443 be
reachable before deploy, or the LE cert request fails.