From 828445a6b3f0889f4b3e597049e20df15d15b52a Mon Sep 17 00:00:00 2001 From: Justin Paul Date: Sat, 6 Jun 2026 11:32:15 -0400 Subject: [PATCH] Add Cloudflare Tunnel connector (profile-gated) to the deploy stack A cloudflared service (opt-in via the 'tunnel' compose profile, token from CLOUDFLARE_TUNNEL_TOKEN) connects the lab to Cloudflare. One public hostname -> http://caddy:80 is sufficient because Caddy does the internal path routing. Mirrors the drawbar tunnel setup. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Justin Paul --- deploy/.env.example | 8 ++++++++ deploy/docker-compose.yml | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/deploy/.env.example b/deploy/.env.example index 321e1db..87f2a5e 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -26,8 +26,16 @@ S3_REGION=us-east-1 # --- Edge (Caddy) --- # Local: ':80' (http://localhost). Production: 'provenance.example.com' for auto-HTTPS. +# Behind a Cloudflare Tunnel, keep ':80' — Cloudflare terminates TLS and the +# tunnel forwards plain HTTP to caddy:80. PROVENANCE_SITE_ADDRESS=:80 +# --- Cloudflare Tunnel (optional) --- +# Enable by setting COMPOSE_PROFILES=tunnel and supplying the connector token +# from the Cloudflare dashboard. Public hostname -> http://caddy:80. +CLOUDFLARE_TUNNEL_TOKEN= +COMPOSE_PROFILES= + # --- Auth / sessions --- SESSION_TTL_DAYS=30 TOKEN_TTL_HOURS=24 diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index 7022340..d87e925 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -86,6 +86,24 @@ services: - frontend restart: unless-stopped + # Cloudflare Tunnel connector. The tunnel/ingress is configured in the + # Cloudflare dashboard; this container just connects. One public hostname + # (e.g. provenance.paul.farm) -> http://caddy:80 is enough, because Caddy + # does the internal path routing (/ -> frontend, /api + /health -> backend). + # + # Opt-in via the "tunnel" profile so local dev doesn't start it. On the lab + # host set COMPOSE_PROFILES=tunnel so `docker compose up -d` includes it. + cloudflared: + image: cloudflare/cloudflared:latest + restart: unless-stopped + command: tunnel --no-autoupdate run + environment: + TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN:-} + depends_on: + - caddy + profiles: + - tunnel + volumes: pgdata: miniodata: