Skip to content
tezvyn:

Structuring Compose files across environments

Source: interviewHardHow cards are made

Summary

Compose override and merge mechanics.

Key points

a base compose.yaml plus override files, the default override auto-merge, and explicit -f flags or extends per environment.

What's really being asked

This probes whether you understand Docker Compose's file-merging model and can keep multi-environment configuration DRY instead of forking entire files that drift apart.

The full answer

Start with a base file, conventionally compose.yaml, holding the common service definitions, networks, and volumes. Compose automatically merges compose.override.yaml on top when you run plain docker compose up, which is ideal for local-only tweaks like bind mounts and debug commands. For other environments create explicit files such as compose.ci.yaml and combine them with docker compose -f compose.yaml -f compose.ci.yaml up. Files are applied left to right: scalars like image or command are overridden by the last file, while mappings such as environment are deep-merged. Mention extends or YAML anchors for sharing fragments, and externalizing secrets via env_file rather than inlining.

The mistakes people make

Maintaining a separate complete compose file per environment, which guarantees drift. Believing a later -f file replaces the earlier one wholesale rather than merging. Hardcoding environment-specific secrets directly in the base file.

What usually comes next

How does merge behave for lists versus maps? How do you verify the final resolved config? What does the COMPOSE_FILE environment variable do? When would you prefer extends over multiple files?

A concrete example

Base compose.yaml defines an api service with its image and ports. compose.override.yaml adds a source bind mount and command running a hot-reload server for local work. compose.ci.yaml instead sets command to run the test suite and points DATABASE_URL at a throwaway database. Locally you run docker compose up and get the dev override automatically; in CI you run docker compose -f compose.yaml -f compose.ci.yaml up, and you confirm the result with docker compose config, which prints the fully merged definition so there are no surprises.

Interview question

When you run docker compose up with no -f flags in a directory containing both compose.yaml and compose.override.yaml, what happens?

  • a.Only compose.yaml is used and the override is ignored
  • b.Compose errors because two files are ambiguous
  • c.compose.override.yaml fully replaces compose.yaml
  • d.Compose merges compose.override.yaml on top of compose.yaml automaticallyCorrect
Why?

Compose auto-loads and deep-merges compose.override.yaml over the base. It does not ignore it (A) nor wholesale-replace the base (C); merging is the defined behavior, not an error (B).

Just read this? Test yourself on what you have been reading.

Read the original → docs.docker.com

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on docker — each one lists the topics its interview covers.

See open roles