diff --git a/README.md b/README.md index b387567..423ac9c 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,50 @@ docker run -d --name gadfly-reports -p 8090:8090 -v gadfly-reports-data:/data \ gitea.stevedudenhoeffer.com/steve/gadfly-reports:latest ``` +### Deploy behind Traefik (expose over a domain) + +```yaml +# docker-compose.yml — publish gadfly-reports at https://reports.example.com via Traefik. +services: + gadfly-reports: + image: gitea.stevedudenhoeffer.com/steve/gadfly-reports:latest + restart: unless-stopped + environment: + # Auth is built in: callers (gadfly emit, gadfly-mcp) send this as a bearer + # token; /healthz stays open. ADDR and DB default to :8090 and + # /data/gadfly-reports.db inside the image. + GADFLY_REPORTS_TOKEN: ${GADFLY_REPORTS_TOKEN:?set GADFLY_REPORTS_TOKEN in .env} + volumes: + - gadfly-reports-data:/data + networks: [traefik] + healthcheck: + test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:8090/healthz"] + interval: 30s + timeout: 5s + retries: 3 + labels: + - "traefik.enable=true" + - "traefik.http.routers.gadfly-reports.rule=Host(`reports.example.com`)" + - "traefik.http.routers.gadfly-reports.entrypoints=websecure" + - "traefik.http.routers.gadfly-reports.tls=true" + - "traefik.http.routers.gadfly-reports.tls.certresolver=letsencrypt" + - "traefik.http.services.gadfly-reports.loadbalancer.server.port=8090" + +volumes: + gadfly-reports-data: + +networks: + traefik: + external: true # the network your Traefik instance is attached to +``` + +Put `GADFLY_REPORTS_TOKEN=` in a `.env` beside the compose file. Tailor the three +Traefik bits to your setup — the **host** (`reports.example.com`), the **entrypoint** +(`websecure`) and the **certresolver** (`letsencrypt`) must match your Traefik config, and the +`traefik` network must be the external one Traefik watches. Traefik terminates TLS and forwards +to the container's `:8090`. Then point `gadfly`'s `GADFLY_FINDINGS_URL` and `gadfly-mcp`'s +`--store` at `https://reports.example.com` (with the same token). + ## HTTP API (the canonical contract) | Method & path | Body / query | Purpose |