Compose, networking, and volumes¶
Play it
Layer Cake: Arrange Dockerfile lines and watch which layers the build cache reuses.
The game links back to this page from: Compose basics, Networking, Volumes.
Compose basics¶
docker compose runs a multi-container application from one YAML file. Good for local
dev stacks (app + database + cache) without hand-wiring docker network/docker run
commands.
# compose.yaml
services:
web:
build: .
ports:
- "8080:80"
environment:
- LOG_LEVEL=debug
depends_on:
- db
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=devpass
volumes:
db-data:
docker compose up -d # start everything in the background
docker compose logs -f web # tail one service's logs
docker compose ps # status of each service
docker compose down # stop and remove containers (add -v to drop volumes too)
depends_on controls start order, not readiness — a database container can accept
connections seconds after its process starts. Use a healthcheck if a dependent service
needs to wait for real readiness:
db:
image: postgres:16-alpine
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 2s
retries: 10
web:
depends_on:
db:
condition: service_healthy
Networking¶
- Compose puts every service in the same project on one bridge network by default;
services reach each other by service name as hostname (
db:5432, notlocalhost:5432). docker runcontainers not in a shared network can't see each other by name — either put them on a user-defined network (docker network create app-net, then--network app-neton eachrun) or use Compose.- Publish a port to the host only when something outside Docker needs it
(
ports: ["8080:80"]); container-to-container traffic never needs a published port.
Volumes¶
- Named volumes (
db-data:above) are managed by Docker and persist acrosscompose down(notdown -v). Use them for data you want to survive container recreation — databases, caches. - Bind mounts (
./src:/app/src) map a host path directly into the container. Useful for live-reloading source code in dev; avoid them for anything that needs to be portable or reproducible in CI. - Data written to a container's writable layer (no volume) is lost when the container is
removed —
docker run --rmmakes this explicit.