Fix: docker-compose.override.yml Not Working — Override File Ignored or Not Merged
Quick Answer
How to fix docker-compose.override.yml not being applied — file naming, merge behavior, explicit file flags, environment-specific configs, and common override pitfalls.
The Problem
A docker-compose.override.yml file exists but its settings aren’t applied:
# docker-compose.override.yml — expected to add volume mount
services:
app:
volumes:
- ./src:/app/src
environment:
DEBUG: "true"docker compose up
# Container starts without the volume mount or DEBUG env var
# Override file is silently ignoredOr an explicit -f flag stops the override from loading:
docker compose -f docker-compose.yml up
# Only docker-compose.yml loaded — override.yml skipped entirelyOr multiple override files conflict:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
# docker-compose.override.yml NOT loaded — explicit -f disables auto-loadingWhy This Happens
Docker Compose has an auto-merge feature: when you run docker compose up with no -f flags, it automatically merges docker-compose.yml with docker-compose.override.yml if both files exist in the current directory.
This auto-merge only happens under specific conditions:
- Exact filename required — the file must be named
docker-compose.override.yml(notdocker-compose.override.yaml, notoverride.yml). The.ymlextension is required, not.yaml, unless your base file uses.yaml. - Must be in the same directory — both files must be in the same directory where you run
docker compose. -fflag disables auto-loading — as soon as you use-fto specify any file, Docker Compose stops auto-loading and only uses the files you explicitly listed.- Docker Compose v1 vs v2 —
docker-compose(v1, Python) vsdocker compose(v2, Go plugin) have minor behavioral differences. Some older setups usedocker-compose.ymlonly and don’t support override files in the same way.
Fix 1: Verify the Filename and Location
The override file must be named exactly docker-compose.override.yml:
# Check what files exist
ls -la docker-compose*.yml docker-compose*.yaml 2>/dev/null
# Correct filename
docker-compose.override.yml ✓
docker-compose.override.yaml ✗ (wrong extension if base is .yml)
docker.compose.override.yml ✗ (dot instead of hyphen)
override.yml ✗ (wrong name)
docker-compose-override.yml ✗ (hyphen instead of dot before override)Verify Compose is actually reading both files:
# Print the merged config — shows what Docker Compose will use
docker compose config
# If override settings appear in the output, the merge is working
# If they don't appear, the override file isn't being loadedCheck the current directory:
pwd
ls docker-compose*.yml
# Must run docker compose from the directory containing both files
# Not from a parent or child directoryFix 2: Understand Merge Behavior
Docker Compose merges files by overlaying the second file on top of the first. The merge rules differ by field type:
# docker-compose.yml
services:
app:
image: myapp:latest
ports:
- "3000:3000"
environment:
NODE_ENV: production
API_URL: https://api.example.com
volumes:
- data:/app/data
# docker-compose.override.yml
services:
app:
ports:
- "3001:3001" # ADDS to ports (lists are appended, not replaced)
environment:
NODE_ENV: development # REPLACES this key (mappings are merged by key)
DEBUG: "true" # ADDS new key
volumes:
- ./src:/app/src # ADDS to volumes (lists are appended)Merged result:
services:
app:
image: myapp:latest # from base
ports:
- "3000:3000" # from base
- "3001:3001" # from override (appended)
environment:
NODE_ENV: development # override wins
API_URL: https://api.example.com # from base
DEBUG: "true" # from override
volumes:
- data:/app/data # from base
- ./src:/app/src # from override (appended)Key merge rules:
- Mappings (objects): Merged by key — override values replace base values for matching keys, new keys are added
- Sequences (lists):
ports,volumes,environmentarrays are appended — not replaced - Scalar values: Override replaces base
Fix 3: Explicit File Loading with -f
When you need to use -f, include both files explicitly:
# WRONG — only loads base file, override skipped
docker compose -f docker-compose.yml up
# CORRECT — load base + override explicitly
docker compose -f docker-compose.yml -f docker-compose.override.yml up
# Multiple overrides — applied left to right
docker compose \
-f docker-compose.yml \
-f docker-compose.override.yml \
-f docker-compose.local.yml \
upAdd a Makefile to avoid typing long commands:
# Makefile
dev:
docker compose up
prod:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
ci:
docker compose -f docker-compose.yml -f docker-compose.ci.yml up --buildFix 4: Environment-Specific Configuration Pattern
A common pattern uses a base file plus environment-specific overrides:
project/
├── docker-compose.yml # Base: shared service definitions
├── docker-compose.override.yml # Dev: auto-loaded, volume mounts, hot reload
├── docker-compose.prod.yml # Prod: explicit -f required
├── docker-compose.ci.yml # CI: explicit -f required
└── .env # Environment variables for all files# docker-compose.yml — base (production-ready defaults)
services:
app:
image: myapp:${TAG:-latest}
restart: unless-stopped
environment:
NODE_ENV: production
networks:
- backend
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
networks:
- backend
volumes:
pgdata:
networks:
backend:# docker-compose.override.yml — development (auto-loaded)
services:
app:
build:
context: .
target: dev # Use dev stage in multi-stage Dockerfile
volumes:
- ./src:/app/src # Hot reload: mount source code
- /app/node_modules # Don't overwrite container's node_modules
environment:
NODE_ENV: development
DEBUG: "app:*"
ports:
- "3000:3000" # Expose port for local access
- "9229:9229" # Node.js debugger port
db:
ports:
- "5432:5432" # Expose DB for local tools (TablePlus, psql)# docker-compose.prod.yml — production differences
# Usage: docker compose -f docker-compose.yml -f docker-compose.prod.yml up
services:
app:
image: registry.example.com/myapp:${TAG}
deploy:
replicas: 3
resources:
limits:
memory: 512MFix 5: Override Specific Fields
Common patterns for overriding specific service properties:
# Override the build context (useful for CI vs local)
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
args:
BUILD_ENV: development
# Override the command (run dev server instead of production server)
services:
app:
command: npm run dev
# Base has: command: node dist/server.js
# Override the entrypoint
services:
app:
entrypoint: /bin/sh -c
command: ["npm run dev"]
# Override health check
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3Remove a value set in the base file — use null to unset:
# docker-compose.yml sets a restart policy
services:
app:
restart: unless-stopped
# docker-compose.override.yml removes it for development
services:
app:
restart: "no" # Override to disable restart in devFix 6: Debug Override Merging
When overrides aren’t applying as expected:
# See the fully merged configuration
docker compose config
# See only the config for one service
docker compose config app
# Validate syntax without running
docker compose config --quiet && echo "Config is valid"
# Check which files Docker Compose is reading
docker compose --verbose config 2>&1 | head -20
# Output includes: "Found project name: myproject"
# and lists the config files being merged
# Run with explicit debug output
COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml docker compose configCheck environment variable substitution:
# .env file values are substituted in compose files
# Verify substitution is working:
docker compose config | grep -A5 "environment:"
# If variables show as empty, check .env file location
# .env must be in the same directory as docker-compose.ymlFix 7: COMPOSE_FILE Environment Variable
Set override files permanently via environment variable instead of -f flags:
# Set in shell (current session)
export COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml
# Set in .env file (persists for the project)
echo "COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml" >> .env
# Now plain 'docker compose up' loads both files
docker compose upDifferent separators by OS:
- Linux/Mac: colon
:separator - Windows: semicolon
;separator
# Windows
COMPOSE_FILE=docker-compose.yml;docker-compose.override.ymlStill Not Working?
Docker Compose v1 vs v2 differences — docker-compose (v1) and docker compose (v2) handle some edge cases differently. If you’re using docker-compose (with hyphen), verify it’s finding the override file:
docker-compose --verbose config 2>&1 | grep -i "override\|reading"Project name mismatch — if you run Docker Compose from different directories or with different project names, it may not recognize existing services. Use COMPOSE_PROJECT_NAME or the -p flag consistently.
Override file encoding — YAML is sensitive to indentation. A tab instead of spaces, or incorrect indentation level, causes the file to parse incorrectly (or silently fail to merge a section). Use docker compose config to confirm the merged output looks right.
For related Docker issues, see Fix: Docker Compose depends_on Not Working and Fix: Docker Compose Networking Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Docker Secrets Not Working — BuildKit --secret Not Mounting, Compose Secrets Undefined, or Secret Leaking into Image
How to fix Docker secrets — BuildKit secret mounts in Dockerfile, docker-compose secrets config, runtime vs build-time secrets, environment variable alternatives, and verifying secrets don't leak into image layers.
Fix: Docker Compose Healthcheck Not Working — depends_on Not Waiting or Always Unhealthy
How to fix Docker Compose healthcheck issues — depends_on condition service_healthy, healthcheck command syntax, start_period, custom health scripts, and debugging unhealthy containers.
Fix: Docker Build ARG Not Available — ENV Variables Missing at Runtime
How to fix Docker ARG and ENV variable issues — build-time vs runtime scope, ARG before FROM, multi-stage build variable passing, secret handling, and .env file patterns.
Fix: Docker HEALTHCHECK Failing — Container Marked Unhealthy Despite Running
How to fix Docker HEALTHCHECK failures — command syntax, curl vs wget availability, start period, interval tuning, health check in docker-compose, and debugging unhealthy containers.