Compose: Declarative Applications
In one sentence: Compose replaces a fragile pile of run commands with one declarative file — services, networks, volumes — and a convergence engine that diffs your declaration against reality and applies only the difference.
You already know
- Every noun in a compose file: images (P2), containers (P4), volumes (P5), networks (P6).
- From Lesson 31: on a shared user-defined network, services find each other by name.
Say what, not how
An imperative deploy script encodes steps; when reality drifts (one container crashed, one image is stale), the script is wrong and humans improvise. A compose file encodes desired state: "these three services, on these networks, with these volumes." A service is a template for containers — image, config, mounts, networks — not a container itself; that indirection is what later lets one service mean five replicas. From one file, the engine derives the whole resource graph and creates a default network so every service can dial every other by service name.
flowchart TB F["compose file (declared intent)
services: web, api, db
volumes: dbdata
networks: default"] F --> W["service web
image web:2 · port 443:8443"] F --> A["service api
image api:5 · env …"] F --> D["service db
image pg:16 · mount dbdata"] F --> NET["network: app_default
(auto-created, embedded DNS)"] F --> VOL[("volume: dbdata")] W --- NET A --- NET D --- NET D --- VOL
Up is a diff, not a script
up means converge: compare declared state with what exists, then create, recreate, or leave alone per resource. Running up twice in a row does nothing the second time — the fixed point is the definition of correctness. Change one service's image and only that service is recreated; the volume and network survive untouched:
sequenceDiagram
participant U as User
participant C as Compose engine
participant E as Engine API
U->>C: up
C->>E: inspect existing: network, volume, 3 containers
E-->>C: all present; api runs image api:4, file says api:5
C->>C: diff → only api differs
C->>E: recreate api container (new image, same network + names)
C->>E: web, db, network, volume: untouched
C-->>U: converged — 1 changed, 4 unchanged
Anchor these
- Declare state; let the engine compute the steps. Reruns are no-ops at the fixed point.
- A service is a container template — the indirection that enables replicas later.
- The auto-created per-app network + name-based DNS is what makes services composable.
See what actually stuck.
Take the practice scenarios now.