## Context
Node.js 18+, TypeScript compiled to `dist/`. Production image must be minimal, non-root, and use the compiled output only.

## Decisions
- Multi-stage build: `builder` stage compiles TypeScript; `production` stage copies `dist/` only
- Base image: `node:18-alpine` — minimal footprint
- Non-root user: `node` user (built into node alpine image)
- No dev dependencies in production image — only `npm ci --omit=dev`
- Health check: `wget` on `localhost:3000/health` — but no `/health` endpoint exists yet, so omit health check from Dockerfile; it is set in docker-compose.yml via pg_isready/redis-cli patterns
- `.dockerignore` excludes: `node_modules`, `dist`, `coverage`, `tests`, `.env`, `*.pem`, `vj_notes`, `.cto-workspace`, `.claude`

## Open Questions
*(none)*
