# Deploy checklist (for a person or an automated agent) Follow in order. Full explanations are in [DEPLOY.md](DEPLOY.md). 1. Host has Docker with Compose v2: `docker compose version`. 2. `git clone https://gitea.cloudfreeiot.com/bkvargyas/courtside.git && cd courtside` 3. `cp .env.example .env` and set: - `ADMIN_PASSWORD` — strong password for `/admin`. - `SESSION_SECRET` — `openssl rand -hex 32`. - `CLOUDFLARE_TUNNEL_TOKEN` — from Cloudflare Zero Trust → Networks → Tunnels → your tunnel → connector token. The tunnel's public hostname must route to **`http://app:3000`**. - `TRUST_CF_ACCESS` — leave `false` unless an Access policy protects `/admin` on that hostname. 4. `docker compose up -d --build` 5. Verify: - `docker compose ps` → `app` healthy, `cloudflared` running. - `docker compose exec app wget -qO- http://127.0.0.1:3000/healthz` → `{"ok":true,...}`. - `docker compose logs cloudflared | grep -i "registered tunnel connection"`. - `curl -sI https:///` → `200`. - `https:///admin` shows the login page and accepts `ADMIN_PASSWORD`. 6. Optional: seed the demo tournament to give the site something to show: `docker compose stop app && docker compose run --rm app node scripts/seed-demo.js && docker compose start app` then open `https:///t/demo-labor-day-2s`. Delete it later from the desk's Danger zone. 7. Back up: the named volume `courtside-data` (one SQLite file). See DEPLOY.md §5. 8. Update later: `git pull && docker compose up -d --build`. Nothing else is required. No host ports are published; no reverse proxy, TLS certificate, or database server is involved.