Keep production and development configs separate. Docker Compose automatically merges compose.override.yml for local development tweaks.
The magic
Compose automatically loads two files:
compose.yml(base configuration)compose.override.yml(local overrides)
# These are equivalent:
docker compose up
docker compose -f compose.yml -f compose.override.yml up
Basic setup
compose.yml (production-ready):
services:
web:
image: myapp:latest
ports:
- "80:80"
environment:
NODE_ENV: production
LOG_LEVEL: warn
compose.override.yml (developer-friendly):
services:
web:
build: . # Build locally instead of using image
ports:
- "3000:80" # Different port for development
volumes:
- .:/app # Mount source code
environment:
NODE_ENV: development
LOG_LEVEL: debug
DEBUG: "true"
Real development example
compose.yml:
services:
frontend:
image: frontend:${VERSION:-latest}
depends_on:
- api
api:
image: api:${VERSION:-latest}
environment:
DATABASE_URL: ${DATABASE_URL}
depends_on:
- postgres
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
compose.override.yml:
services:
frontend:
build: ./frontend
volumes:
- ./frontend:/app
- /app/node_modules
command: npm run dev
ports:
- "3000:3000"
api:
build: ./api
volumes:
- ./api:/app
environment:
DATABASE_URL: postgres://postgres:localpass@postgres/devdb
FLASK_DEBUG: "1"
ports:
- "5000:5000"
postgres:
environment:
POSTGRES_PASSWORD: localpass
ports:
- "5432:5432"
volumes:
- postgres_dev:/var/lib/postgresql/data
volumes:
postgres_dev:
Exclude override in production
Deploy without override file:
# Production deployment - override.yml ignored
docker compose -f compose.yml up -d
# Or explicitly with production override
docker compose -f compose.yml -f compose.prod.yml up -d
Multiple override files
Chain multiple configurations:
# Base + override + additional testing setup
docker compose \
-f compose.yml \
-f compose.override.yml \
-f compose.test.yml \
up
Check merged configuration
See the final result:
# View merged configuration (both files)
docker compose config
# View with explicit files
docker compose -f compose.yml -f compose.override.yml config
# Production config without override
docker compose -f compose.yml config
# Save merged config
docker compose config > composed.yml
Common patterns
Enable debugging tools:
# compose.override.yml
services:
web:
command: npm run dev
environment:
DEBUG: "*"
ports:
- "9229:9229" # Node debugger
Add development services:
# compose.override.yml
services:
mailhog: # Email testing
image: mailhog/mailhog
ports:
- "8025:8025"
Pro tip
Add compose.override.yml to .gitignore for personal settings:
echo "compose.override.yml" >> .gitignore
# Provide a template
cp compose.override.yml compose.override.yml.example
git add compose.override.yml.example
Developers copy the example and customize locally without affecting others.