Phase 7c: Local Dev Stack (Docker Compose + Tailscale)

phase-mcd-tracker-7c-local-dev Phase

phase
Goal: Full local dev stack in Docker Compose with Tailscale funnel — test auth, API, data binding, and Capacitor web fallbacks locally in seconds, not minutes via CI.
Owner: Dev agent + Lucas (verification)
Repo: mcd-tracker-app (docker-compose.yml lives here)
Depends on: Phase 7 (app scaffold exists)

Scope

Lesson (2026-03-16): Phase 7 skipped local dev entirely. Six production hotfixes — wrong port, wrong registry, wrong realm, check-sso redirect, no CORS, client not public. All caught in seconds with docker compose up. The rule: if it doesn't work locally, it doesn't get pushed.
Docker Compose services:
  • app — SvelteKit dev server (npm run dev), hot reload, port 5173. VITE_API_URL=http://api:8000
  • api — mcd-tracker-api (FastAPI), port 8000. DATABASE_URL pointing to local postgres. KEYCLOAK_REALM_URL pointing to local keycloak.
  • postgres — Postgres 16-alpine, seeded with test data (locations, codes, receipts)
  • keycloak — Keycloak dev mode, pre-configured mcd-tracker realm with mcd-tracker-app public client, test users, redirect URIs for localhost
Environment variable:
  • Add VITE_API_URL to src/lib/api.js: const API_BASE = import.meta.env.VITE_API_URL || 'https://mcd-tracker.tail5b443a.ts.net'
  • Docker Compose sets it to http://localhost:8000 (or http://api:8000 for container-to-container)
  • Production build uses the default (no env var needed)
Tailscale funnel:
  • Official URL like mcd-dev.tail5b443a.ts.net or subpath on playground
  • Accessible from phone on Tailscale network
  • Listed on playground.tail5b443a.ts.net hub landing page
Seed data:
  • Script to populate test locations (5-10 McDonald's), test codes (mix of active, redeemed, expired), test receipts
  • 4 Keycloak test users: testuser, testuser2, testadmin, emptyuser
  • Realm export JSON for reproducible Keycloak setup
Docker Compose → Kustomize mapping:
  • Same containers, same env vars, same ports — different orchestrator
  • docker-compose.yml is the local dev definition, kustomize overlay is the prod definition
  • Both stay in sync — changes to one should reflect in the other
SOP gate:
  • Update sop-frontend-experiment and Phase 7 steps: "run docker compose up, test full flow locally, THEN push to prod"
  • Update project-capacitor-mobile local dev workflow section (already created this session)

Deliverables

  • pending
  • plan-mcd-tracker — parent plan
  • phase-mcd-tracker-7-sveltekit — parent phase
  • project-capacitor-mobile — local dev workflow doc (updated this session)
  • todo-service-onboarding-validation — deployment validation TODO