Compose Override — Environment-Specific Configuration Without Duplication
What Is a Compose Override in Simple Terms?
Your development setup needs bind mounts for hot reloading. Your CI setup needs different port numbers. Your production setup needs resource limits. Instead of maintaining three completely separate compose files, you maintain one base file and small override files that add or change only what is different per environment.
Docker automatically merges docker-compose.override.yml with docker-compose.yml when both exist in the same directory.
docker-compose.yml <- base: what all environments sharedocker-compose.override.yml <- automatically merged (dev by default)docker-compose.prod.yml <- production overrides (specify with -f)docker-compose.ci.yml <- CI overrides (specify with -f)Example: Base + Override Pattern
# docker-compose.yml — base (shared across all environments)version: "3.8"services: api: image: payment-api:latest environment: NODE_ENV: production DB_HOST: postgres depends_on: postgres: condition: service_healthy postgres: image: postgres:15-alpine environment: POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: * postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready"] interval: 10s volumes: postgres-data:# docker-compose.override.yml — development overrides (auto-merged)version: "3.8"services: api: build: . # build locally in dev environment: NODE_ENV: development DEBUG: "*" volumes: * ./src:/app/src # hot reloading ports: * "3000:3000" * "9229:9229" # debugger port command: ["npm", "run", "dev"] postgres: ports: * "5432:5432" # expose for local DB GUI environment: POSTGRES_PASSWORD: devpassword# docker-compose.prod.yml — production overrides (use with -f)version: "3.8"services: api: restart: unless-stopped deploy: resources: limits: cpus: "1.5" memory: 512M logging: driver: json-file options: max-size: "100m" max-file: "3"Using Override Files
# Development (docker-compose.override.yml auto-merged)docker compose up -d# Merges: docker-compose.yml + docker-compose.override.yml # Production (explicit file selection)docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d# Merges: base + prod overrides only # CI (explicit file selection)docker compose -f docker-compose.yml -f docker-compose.ci.yml up -d # See the fully merged result before runningdocker compose config# Shows the final merged configurationPLACEMENT PRO TIP**Tip:** Use `docker compose config` to preview the fully merged compose file before running it. This is the fastest way to verify your override files are being merged as expected — especially useful when debugging why a service has unexpected configuration.