A file named compose.override.yaml next to compose.yaml is read and merged on top automatically. It suits settings only a developer's machine wants, such as Node.js 2,131 's inspector, which VS Code 550 or Chrome DevTools 3,948 attach to:
# Development additions, merged over compose.yaml automatically.
services:
api:
command: ["node", "--inspect=0.0.0.0:9229", "server.js"]
environment:
NODE_ENV: development
ports:
- "127.0.0.1:${DEBUG_PORT:-9229}:9229"echo DEBUG_PORT=33229 >> .env
docker compose config api | grep -E 'inspect|NODE_ENV|published: "330|published: "332'
docker compose up -d api 2>&1 | grep 'api-1 Started'
sleep 2; curl -s localhost:33229/json/version | grep Browser - --inspect=0.0.0.0:9229
NODE_ENV: development
published: "33000"
published: "33229"
Container l3-booknest-api-1 Started
"Browser": "node.js/v24.21.0",Mappings such as environment merge key by key, the later file winning; most lists are appended, but ports, volumes, secrets and configs are de-duplicated by target; command, entrypoint and a healthcheck's test are replaced. The YAML tag !reset empties an inherited value and !override replaces it whole. Across files, extends: {file: common.yaml, service: node-base} copies a service and applies local keys on top. A committed override silently reaches every colleague, so the next subsection renames it.