The next lab gives you the signup app's source, a Dockerfile and a .env file, plus a written brief. You write compose.yaml from scratch. Every key you need appeared in this chapter.
Requirement to key
| Requirement | Key | Lesson |
|---|---|---|
| Build the app from the local Dockerfile | build: | 3 |
| Publish a host port to the app's port | ports: | 3 |
| Pass a value into a container | environment: | 3 |
| Keep a secret out of compose.yaml | .env + ${VAR} | 6 |
Keep database files across down | service volumes: + top-level volumes: | 4 |
| Report when Postgres accepts connections | healthcheck: with pg_isready | 7 |
| Start the app only after that | depends_on: + condition: service_healthy | 7 |
Facts the app depends on
text
web (python app.py) db (postgres:16)
listens on $PORT, default 5000 listens on 5432 (project network only)
connects to host $DB_HOST, default db first start: password = $POSTGRES_PASSWORD
password from $DB_PASSWORD data in /var/lib/postgresql/data
exits 1 if Postgres refuses or is not readyThe service holding Postgres must be named db, or DB_HOST must be set to its name.
Work in small steps
text
edit compose.yaml ─► docker compose config ─► docker compose up -d ─► docker compose ps -a
▲ │ error │
└────────────────────┴──────── docker compose logs SERVICE ◄──────────┘ not running- Start with
dbalone and get it to(healthy). - Add
web. Checkdocker compose exec web envforDB_PASSWORD. - Add a signup with
curl -s -X POST 'localhost:8000/signup?name=...'. - Run
docker compose down, thendocker compose up -d, and read the count again.
Errors you may meet
| Output | Cause |
|---|---|
yaml: line N: ... | indentation or list/mapping mix-up near line N |
additional properties 'X' not allowed | key misspelled or at the wrong level |
refers to undefined volume | volume missing from the top-level volumes: |
has no healthcheck configured | service_healthy used without a healthcheck |
password authentication failed | DB_PASSWORD empty or different from the database's password |
could not translate host name "db" | the Postgres service has a different name |