underlay
module 1010–15h

Capstone

One shipped product

Every module so far built a muscle. The capstone puts them in one body: a real product, with real users (even if 'users' is you), behind SSL, with tests, backups, monitoring and cost tracking. Suggested build: a RAG support assistant for your own business — docs in, answers out, every query priced.

The skeleton: every piece from this course in one compose file

This is the shape of the thing you'll ship. Note what's here: the app, the database with a volume, the cache, the proxy — plus healthchecks so the stack heals itself, and the deploy pipeline you built in module 6:

yamlthe capstone stack — you've built every line of this
services:
  app:
    build: .
    restart: unless-stopped
    environment:
      - DATABASE_URL=postgresql://app:app@db:5432/app
      - REDIS_URL=redis://redis:6379
      - OPENAI_API_KEY=${OPENAI_API_KEY}     # from the server's .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 10s
      start_period: 5s
    depends_on:
      db: { condition: service_healthy }

  db:
    image: postgres:18-alpine
    restart: unless-stopped
    environment: { POSTGRES_USER: app, POSTGRES_PASSWORD: app }
    volumes: [pgdata:/var/lib/postgresql/data]

  redis:
    image: redis:8-alpine
    restart: unless-stopped

volumes:
  pgdata:

The backup drill — the check that makes you sleep

A backup you've never restored is a hope, not a plan. The drill, once a week until it's boring: dump the database, ship it off-box, then prove you can eat it back:

bashbackup + restore drill — do this until it's boring
# backup (cron it, and ping healthchecks.io when done)
docker compose exec -T db pg_dump -U app app > backup-$(date +%F).sql
restic backup backup-*.sql            # encrypted, off-box
healthchecks.io_ping                  # the cron watchdog

# THE DRILL — restore into a scratch database:
docker compose exec -T db createdb -U app scratch
docker compose exec -T db psql -U app -d scratch < backup-$(date +%F).sql
docker compose exec -T db psql -U app -d scratch \
  -c "SELECT count(*) FROM orders;"   # prove the data is there

The postmortem — the actual graduation

When it breaks — and it will break — write it down: what broke, how you found it, what the fix was, and what you'll check first next time. Three paragraphs, no blame. That document is the difference between a course you finished and an engineer you became.

textPOSTMORTEM.md — the template
# Incident: <one line>

- What broke:            <symptom + status code>
- How I found it:        <log line, monitor, user report>
- Root cause:            <one honest paragraph>
- The fix:               <the diff, in words>
- What I check first:    <the new habit>
- Time to fix:           <hours>

Scored by the eval, deployed behind SSL, restored from backup:
<paste your check evidence here>

test yourself

01The capstone is graded by:

02A postmortem should contain:

03Why track cost per query (Langfuse)?

the real check

Scored by an automated eval, deployed behind SSL, restored from backup.

0 stamps earned·streak: 0 days

Signed out: progress lives in this browser. to carry it everywhere.

vibe-coder payoff

Everything above, on one real product you own.