How it works
The explanation, with examples you can run.
A web service with a cache
# compose.yamlservices: web: build: ./node ports: - "127.0.0.1:8765:3000" environment: REDIS_URL: redis://cache:6379 depends_on: cache: condition: service_healthy cache: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 volumes: - cache-data:/datavolumes: cache-data:docker compose up -d --wait# Container demo-cache-1 Healthy# Container demo-web-1 Healthydocker compose ps --format '{{.Service}} {{.Status}}'# cache Up 6 seconds (healthy)# web Up Less than a secondcurl -s localhost:8765# hello from d9eb232cfb16docker compose exec cache redis-cli -h cache ping# PONGdocker compose down -v # containers, network, and the cache-data volumeWhat happened: Compose built web from ./node, created the network demo_default (the project name defaults to the directory name), created the volume, started cache, waited until its healthcheck passed, then started web. --wait returns once the services are running or healthy, which is handy in CI before running tests.
Details that matter
- No
version:line. The top-levelversionkey is obsolete; current Compose printsthe attribute 'version' is obsolete, it will be ignoredand uses the Compose Specification regardless. - Readiness, not just order.
depends_onin short form waits only for the container to start. Give dependencies ahealthcheckand usecondition: service_healthy. Your app should still retry connections; dependencies restart in real life too. - Ports for humans, names for services. Publish only what you open in a browser or a local tool, bound to
127.0.0.1. Services talk to each other over the project network by name, on the container port. - Overrides. Compose automatically merges
compose.override.yaml, which is a good place for developer-only settings such as bind mounts and debug ports.profiles:keep optional services (an admin UI, a load generator) off unless asked for. - Live code.
develop.watchwithdocker compose watchsyncs changed files into the container or rebuilds the image when dependency files change, often faster than bind-mounting the whole tree on Docker Desktop. - Secrets. Do not commit real secrets to
environment:. Use an untracked.envfile for local values, or Composesecrets:to mount them as files.
Where Compose stops
Compose runs containers on one Docker engine. It restarts a crashed container if you set restart:, but it does not move work to another machine, roll out new versions gradually, or scale on load. Those are the jobs of an orchestrator, which is where Kubernetes takes over, built on the same images, networking and volume ideas.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.