Part 11: Docker Compose
In Part 10: Postgres in a container we ran Postgres as one container and the app locally against it. That works, but we want to run both of them at the same time with one command.
We use Docker Compose to put the app image and Postgres in one file, then run one command to start both services together.
Describe the stack
Ask the assistant for a Compose file with both services:
Write a compose.yaml with a postgres service and the app service built from
the Dockerfile
Give Postgres a named volume so data survives
Make the app wait for Postgres to be ready
This writes a compose.yaml at the repo root, the modern name that Compose now
prefers while still reading docker-compose.yml too.
The generated file looks like this:
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: snakearena
POSTGRES_PASSWORD: snakearena
POSTGRES_DB: snakearena
volumes:
- snake_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U snakearena -d snakearena"]
interval: 5s
timeout: 5s
retries: 5
start_period: 5s
app:
build:
context: .
dockerfile: Dockerfile
environment:
SNAKE_ROYALE_DATABASE_URL: postgresql://snakearena:snakearena@postgres:5432/snakearena
ports:
- "8000:8000"
depends_on:
postgres:
condition: service_healthy
volumes:
snake_pgdata:
Compose makes this convenient in two ways:
- The app reaches the database at the hostname
postgres, the service name on the Compose network, so there's nohost.docker.internaljuggling. depends_onwith the Postgres healthcheck holds the app back until the database is ready to accept connections.
Bring the stack up
Bring the whole stack up with one command:
docker compose up --build
The app is at localhost:8000, with the
API docs alongside it. Sign up and submit a score,
then bring the stack down and up again - the snake_pgdata volume keeps the
data. Stop the stack with docker compose down.
Commit the Compose setup:
git add .
git commit -m "Add Docker Compose for app and Postgres"
We take this same app image to a real server in Part 12: Deploy to AWS with infrastructure as code.