Quiz
Capstone warm-up: you are handed a Python web app with a requirements.txt and a Postgres database. From lessons 3-1 and 5-1, which two files turn it into a one-command runnable stack?
The app we're shipping
A small notes API called notesy: Python, a server.py listening on port 8000, storing notes in Postgres, with a /health endpoint (lesson 9-2) that checks its database connection. The repo:
notesy/ ├── server.py ├── requirements.txt ├── tests/ │ └── test_notes.py └── .git/
The mission across two lessons, using only things you have learned:
- Dockerfile → image (unit 3)
- compose file with app + db, volume, healthcheck (units 4, 5, 9)
- GitHub Actions pipeline: test → build → push → deploy (units 7, 8)
Step zero, before any building: .dockerignore, from lesson 3-3:
.git __pycache__ .env
The Dockerfile
FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 8000 CMD ["python", "server.py"]
Every line is a lesson you've done: pinned slim base (3-1, 6-2), dependencies copied before code so edits don't reinstall packages (3-3 cache), EXPOSE as documentation, one CMD.
Build and smoke-test it locally:
docker build -t notesy:dev . docker run --rm -p 8080:8000 notesy:dev
(--rm auto-removes the container when it stops, handy for throwaway runs.) It starts, then crashes: no database. Correct behavior, and exactly why compose exists.
The compose file
services:
app:
build: .
ports:
- "8080:8000"
environment:
DATABASE_URL: postgres://notesy:devpass@db:5432/notesy
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
environment:
POSTGRES_USER: notesy
POSTGRES_PASSWORD: devpass
POSTGRES_DB: notesy
volumes:
- dbdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "notesy"]
interval: 5s
retries: 5
volumes:
dbdata:Read it as a tour of the course: service names as hostnames (4-2, 5-1), env config matching on both sides (5-2), a named volume so notes survive (4-1), and a real healthcheck gating startup with service_healthy (9-2). pg_isready is Postgres's own readiness probe command.
docker compose up -d, then curl localhost:8080/health answers ok. The stack is alive.
Quiz
In the notesy compose file, why does DATABASE_URL use the hostname db instead of localhost?
Problem
A teammate runs docker compose down, then up again, and worries the saved notes are gone. Which single line of the compose file (inside the db service) guarantees the data survived? Answer with the line.