Layering Compose Files
Layering Compose Files
Multiple -f flags merge in order; later files add to or override earlier ones:
docker compose -f compose.yml -f compose.prod.yml up -d
You can even skip -f: if both compose.yaml and compose.override.yaml exist in the directory, Compose combines them automatically — the base stays the developer default and the override is often git-ignored per machine. Override files do not need to be complete Compose files; a fragment containing just services.web.ports is valid, because only the merged model must be complete.
Merge Rules
Merge Rules
The rules follow YAML shape:
| Shape | Behavior | Examples |
|---|---|---|
| scalar | later file replaces | image, command |
| mapping | keys merged, local wins | environment, labels |
| sequence | appended from override | ports, dns, tmpfs |
| keyed lists | merged by unique key | volumes by mount path, secrets by name |
One sharp edge: command, entrypoint, and healthcheck.test are overridden wholesale, not appended. And because ports concatenate, declaring the same port in base and override yields two entries — use !override to replace the whole list instead.
Paths, Reset, and Pitfalls
Paths, Reset, and Pitfalls
All relative paths — build contexts, bind mounts, env_file — resolve against the base file (the first -f, or the directory Compose found compose.yaml in). An override in another folder does not rebase them; --project-directory changes the anchor, and the top-level include element is the fix when you want each file resolved from its own location.
To delete a declaration rather than replace it, tag it with !reset:
services:
web:
volumes: !reset []
!override forces full replacement where normal merge would append. Interview: pick -f layering for CI vs include for shared team files, and explain how docker compose config proves the merge before you up.
Quiz
1. When both compose.yaml and compose.override.yaml sit in the working directory, what happens?
2. How are sequence fields like ports merged?
3. Relative bind-mount paths in an override file resolve against:
Flashcards
Question
-f ordering
Click to reveal answer
Answer
Files merge left to right; the last file wins scalar conflicts.
Question
Sequence merge
Click to reveal answer
Answer
ports/dns/tmpfs lists concatenate rather than replace.
Question
!reset / !override
Click to reveal answer
Answer
YAML tags to remove a declaration or force whole-value replacement during merge.
Question
Base-path anchor
Click to reveal answer
Answer
All relative paths resolve from the first -f file's directory.
Question
compose config
Click to reveal answer
Answer
Prints the merged model — verify layering before deploying.
Revision Notes
Key Takeaways
- 1. Base file for shared truth, overrides for environment variance
- 2. Scalars replace, maps merge, sequences append
- 3. Anchor paths to the base file or switch to include
Interview Tips
- • Predict the merged output of two given files field by field
- • Explain when append-style merging bites (duplicate ports) and the tag that fixes it
Cheat Sheet
-f base -f override merge L→R; scalars replace, maps merge, sequences append (ports!); paths from base file; !reset/!override; docker compose config to verify.