Demo code for the JunctionX Kathmandu talk. A simple multi-service app (React frontend + Express API + Postgres) used to teach Docker, Docker Compose, and deployment to AWS App Runner.
.
├── frontend/ React (Vite) app — lists rides from the API
├── api/ Express API + Postgres (pg)
├── frontend-watch/ Tiny app for the `docker compose watch` demo
├── compose.yaml Full stack: healthchecks, networks, named volume
├── compose.broken.yaml Race-condition version (no healthcheck) for Section 5a
├── compose.watch.yaml Live-reload demo for Section 6
├── demos/ Step-by-step scripts, one per section
├── aws/ ECR + App Runner setup + deploy scripts
└── CHEATSHEET.md Every command in one place
| Service | URL |
|---|---|
| frontend | http://localhost:3000 |
| api | http://localhost:4000 |
| api rides | http://localhost:4000/rides |
| frontend-watch | http://localhost:3001 |
| postgres | localhost:5432 |
docker compose up
# open http://localhost:3000demos/01-docker-basics.sh # Section 2 — build + run one container
demos/02-pain-demo.sh # Section 3 — broken docker run, then fixed with a network
demos/03-compose.sh # Section 4 — one file, one command
demos/04-healthcheck.sh # Section 5a — race condition vs healthcheck
demos/05-volumes.sh # Section 5c — data persistence
demos/06-watch.sh # Section 6 — live reloadRun the blocks one at a time on stage (especially the pain demo) — don't execute the whole script at once; some steps fail on purpose.
See aws/setup.md. Do the one-time setup before the talk; the on-stage step is
just ./aws/03-deploy.sh.
- The frontend fetches the API at
http://localhost:4000because the browser runs on your host, not inside the Docker network. Container-to-container, you'd use the service name (http://api:4000) — that's the service-discovery point in Section 4. - The API serves
/and/healtheven without a database, so it stays healthy on App Runner./ridesneeds Postgres.