Command Palette

Search for a command to run...

Hectal
PHASE 5Intermediate ~14 min· topic 1 of 3

Topic 5.1

Why Compose & Your First compose.yaml

In one line

Compose turns a page of docker run commands you'd have to remember and retype into one readable, version-controlled YAML file that anyone on your team can run identically.

0/3 · 0%

Think of it like this

A restaurant's prep list versus one chef trying to remember 15 separate verbal instructions every single morning. Writing it all down ONCE as a checklist means anyone (a new chef, a substitute) can follow the exact same steps perfectly, every time, without relying on memory.

Key ideas

  1. 01

    Without Compose, running a Spring Boot app + Postgres + Redis together means manually creating a network, then three separate long docker run commands with the right flags, env vars, and port mappings, in the right order, every single time you want to start your stack — tedious and error-prone to repeat or share with teammates.

  2. 02

    A compose.yaml file (the modern standard filename; you'll also see the older docker-compose.yml in existing projects — both work) describes ALL of your services, their images/builds, ports, environment variables, volumes, and how they connect — declaratively, in one file.

  3. 03

    docker compose up reads that file and starts EVERYTHING it describes, in the correct dependency order, on an automatically-created shared network where every service can reach every other service BY NAME (exactly the DNS mechanism from Phase 4.3) — with zero manual network setup.

  4. 04

    docker compose down stops and removes everything Compose started (containers and the network it created) in one command — the exact reverse of up, keeping your system clean between runs.

  5. 05

    Each top-level entry under services: becomes one container, using its own service name as both the YAML key and the DNS name other services will use to reach it — this single naming convention is what makes jdbc:postgresql://db:5432/mydb work with zero extra configuration when db is a service name in the same file.

In your stack

  • →

    A realistic minimal Spring Boot + Postgres compose.yaml is genuinely just ~15 lines and replaces a network create, two docker run commands, and remembering which env vars and ports go where — every teammate runs docker compose up and gets the identical local stack.

Code & diagrams

compose.yamlmarkdown

A complete, runnable Spring Boot + Postgres stack in one file.

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - pgdata:/var/lib/postgresql/data   # named volume, survives `compose down`

  app:
    build: .                              # build from the Dockerfile in this directory
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/mydb
      SPRING_DATASOURCE_PASSWORD: secret
    depends_on:
      - db                                 # start db before app

volumes:
  pgdata:                                  # declares the named volume Docker manages
compose-commands.shmarkdown
# Start everything (build images if needed, create network+volumes, start all services)
docker compose up

# Same, but detached (returns your terminal immediately)
docker compose up -d

# See logs from ALL services, combined and color-coded per service
docker compose logs -f

# Stop and remove everything Compose created (containers + network; volumes SURVIVE by default)
docker compose down

# Stop and remove EVERYTHING including named volumes — irreversible data loss, be careful
docker compose down -v

# Rebuild images before starting (after you changed your Dockerfile or source code)
docker compose up --build

Explain it without notes

01

Why does jdbc:postgresql://db:5432/mydb in the app service's environment work correctly with zero extra network configuration?

02

What's the practical difference between docker compose down and docker compose down -v, and why does that distinction matter enormously for a database service?

Practice

01

Write and run this exact compose.yaml (or an equivalent for any app+database pair you have) and confirm both services start and can reach each other.

02

Run docker compose down (without -v), then docker compose up again, and confirm your database data survived. Then run docker compose down -v and confirm it did NOT.

Trade-offs

  • ↔

    Compose is designed for single-host development and simple deployments — it is NOT a replacement for a real orchestrator (Kubernetes, Docker Swarm) when you need multi-host scaling, automated failover, or rolling deployments across a fleet of machines. Phase 8 draws this line clearly.

Done when you can

  • I can write a compose.yaml for a simple two-service app from memory.

  • I know exactly what down -v does and never run it carelessly on real data.

  • I understand that Compose service names double as DNS names automatically.