Infrastructure guardrails for QuizApp (Docker, Compose, runtime wiring). Trigger: When scaffolding or modifying infra/, Dockerfiles, or deployment configs.
infra/ folder (Dockerfiles, compose, env templates)docs/architecture.mdinfra/
├── docker-compose.yml
├── frontend.Dockerfile
├── backend.Dockerfile
└── README.md (explain ports, env, volume usage)
infra/ and reference Dockerfiles via relative paths (e.g., build: { context: .., dockerfile: infra/frontend.Dockerfile })| Service | Port (container → host) | Notes |
|---|---|---|
frontend | 3000:3000 | Runs next start; use env NEXT_PUBLIC_API_BASE_URL=http://backend:4000 or Compose network alias |
backend | 4000:4000 | Runs Express build output (node dist/app.js) |
frontend can reach http://backend:4000 internally; do not expose backend publicly unless required.Frontend:
builder, runner)node:20-alpine (matches engines)pnpm fetch), then pnpm --filter frontend....next/, node_modules for production only (use next build && next start)PORT=3000, HOST=0.0.0.0Backend:
builder compiles TypeScript, runner copies dist/)pnpm fetch + pnpm install --offline to leverage the lockfilePORT=4000node dist/app.jsShared package should be built in the builder stage via pnpm --filter shared build before frontend/backend builds.
.env.example → .env with explicit env_file: entries; never rely on host envs implicitlydepends_on so backend is ready before frontend tries to proxy API callsvolumes: override only for dev (e.g., .:/app + pnpm install), but default compose stack should run the built artifactsinfra/README.md/api to backend:4000; do not open CORS on backend unless Compose rewrites prove impossiblehttp://localhost:3000 and let rewrites map to backend automatically.git, no local dev config)latest tags, always build from the local sourcepackage.json enginespnpm install twice (use pnpm fetch + pnpm install --offline once per stage)node user when possible.env values directly into images—pass through env vars at runtime# Build & run the stack locally (from repo root)
# Tear down containers and remove orphaned services
# Rebuild a single service
docker compose -f infra/docker-compose.yml build backend
# Follow logs
# Clean dangling images created during local iterations