# pocket-id stack — caddy (TLS) + anubis (PoW anti-bot) + pocket-id. # # Topology: # Internet --> caddy:443 --> anubis-pid:8923 --> pocket-id:1411 # # Only caddy publishes ports. pocket-id and anubis are internal-only and # reachable by service name. To bypass anubis (no PoW challenge), point the # Caddyfile reverse_proxy at pocket-id:1411 directly and remove the anubis # block. name: pocket-id volumes: pocket-id-data: caddy-data: caddy-config: services: # --------------------------------------------------------------------------- # Caddy — TLS termination + reverse proxy. The only service on 80/443. # Auto-issues Let's Encrypt cert for ${POCKETID_DOMAIN}. # --------------------------------------------------------------------------- caddy: image: caddy:${CADDY_TAG:-2-alpine} container_name: caddy restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" # HTTP/3 volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data - caddy-config:/config environment: POCKETID_DOMAIN: "${POCKETID_DOMAIN}" ACME_EMAIL: "${ACME_EMAIL}" # Only used by the optional WebFinger block (appended by deploy.sh when # BASE_DOMAIN is set). Empty otherwise -- harmless. BASE_DOMAIN: "${BASE_DOMAIN:-}" REDIRECT_URL: "${REDIRECT_URL:-}" depends_on: - pocket-id healthcheck: test: ["CMD", "wget", "-qO-", "http://127.0.0.1:2019/config/"] interval: 30s timeout: 5s retries: 3 start_period: 10s # --------------------------------------------------------------------------- # Pocket-ID — OIDC provider. No host port published; Caddy fronts it. # TRUST_PROXY=true is required so client IPs and scheme are read from # X-Forwarded-* headers Caddy sets. # --------------------------------------------------------------------------- pocket-id: image: ghcr.io/pocket-id/pocket-id:${POCKETID_TAG:-v2} container_name: pocket-id restart: unless-stopped env_file: .env environment: # Override .env defaults so the container always sees the right values # regardless of how .env is laid out. APP_URL: "https://${POCKETID_DOMAIN}" TRUST_PROXY: "true" volumes: - pocket-id-data:/app/data healthcheck: test: ["CMD", "/app/pocket-id", "healthcheck"] interval: 90s timeout: 5s retries: 2 start_period: 10s # --------------------------------------------------------------------------- # Anubis — PoW anti-bot sidecar in front of pocket-id. Generate the key # with `openssl rand -hex 32`. To disable: comment this service out and # change the Caddyfile reverse_proxy target to `pocket-id:1411`. # --------------------------------------------------------------------------- anubis-pid: image: ghcr.io/techarohq/anubis:${ANUBIS_TAG:-latest} container_name: anubis-pid restart: unless-stopped environment: BIND: ":8923" TARGET: "http://pocket-id:1411" DIFFICULTY: "4" # SHA-256 leading zeros; 4 ≈ 1s client work COOKIE_DOMAIN: "${POCKETID_DOMAIN}" METRICS_BIND: ":9090" ED25519_PRIVATE_KEY_HEX: "${ANUBIS_PID_KEY}" depends_on: pocket-id: condition: service_healthy