Phase 7c: Local Dev Stack (Docker Compose + Tailscale)
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:8000api— mcd-tracker-api (FastAPI), port 8000.DATABASE_URLpointing to local postgres.KEYCLOAK_REALM_URLpointing to local keycloak.postgres— Postgres 16-alpine, seeded with test data (locations, codes, receipts)keycloak— Keycloak dev mode, pre-configuredmcd-trackerrealm withmcd-tracker-apppublic client, test users, redirect URIs for localhost
Environment variable:
- Add
VITE_API_URLtosrc/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(orhttp://api:8000for container-to-container) - Production build uses the default (no env var needed)
Tailscale funnel:
- Official URL like
mcd-dev.tail5b443a.ts.netor subpath on playground - Accessible from phone on Tailscale network
- Listed on
playground.tail5b443a.ts.nethub 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-experimentand Phase 7 steps: "rundocker compose up, test full flow locally, THEN push to prod" - Update
project-capacitor-mobilelocal dev workflow section (already created this session)
Deliverables
- pending
Related
plan-mcd-tracker— parent planphase-mcd-tracker-7-sveltekit— parent phaseproject-capacitor-mobile— local dev workflow doc (updated this session)todo-service-onboarding-validation— deployment validation TODO