Using Multiple Docker Compose Files — A Pro Technique for Flexible Environments

Author

Kritim Yantra

Apr 25, 2025

Using Multiple Docker Compose Files — A Pro Technique for Flexible Environments

When working on real-world projects, it's common to have different environments like development, testing, and production — each requiring slightly different configurations.

Instead of maintaining completely separate docker-compose.yml files, Docker lets you use multiple Compose files together. This makes your setup modular, reusable, and easy to maintain.

In this blog, we’ll explore:

  • 🤔 Why use multiple Compose files?
  • 🔍 How Docker merges Compose files
  • 🛠️ Real-world examples
  • 💡 Best practices

Let’s dive in!


🤔 Why Use Multiple Compose Files?

Here are a few scenarios where using multiple Compose files makes life easier:

Scenario Solution
Dev vs Prod environments Override services with a docker-compose.override.yml
Custom test setups Add a docker-compose.test.yml for CI/CD
Secrets or credentials Keep sensitive info in a separate file
Optional services Add services like adminer, mailhog, or mock-apis without bloating main file

🗂️ How Compose Files Work Together

Docker merges multiple Compose files in order.

docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
  • The first file is the base configuration.
  • The second file (and beyond) overrides or adds to it.

This layered approach is similar to inheritance.


📁 File Structure Example

my-app/
├── docker-compose.yml              # base (common to all environments)
├── docker-compose.override.yml     # automatically picked up (for dev)
├── docker-compose.prod.yml         # production overrides
├── docker-compose.test.yml         # testing setup

🧪 Example Use Case: Dev vs Prod

docker-compose.yml (base)

version: "3.9"
services:
  web:
    build: .
    ports:
      - "80:80"
  db:
    image: postgres:14

docker-compose.override.yml (dev environment)

services:
  web:
    volumes:
      - .:/app
    environment:
      - DEBUG=true

Docker Compose automatically applies override.yml when you run:

docker-compose up

To use only the base config (e.g., in production), skip the override:

docker-compose -f docker-compose.yml up

Or apply a custom override:

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

🧑🔬 Testing Setup Example

docker-compose.test.yml

services:
  web:
    command: ["npm", "run", "test"]
  db:
    image: postgres:14
    environment:
      - POSTGRES_DB=test_db

Run your test stack:

docker-compose -f docker-compose.yml -f docker-compose.test.yml up --abort-on-container-exit

🛠 Common Command Patterns

Use Case Command
Dev environment docker-compose up (uses override by default)
Production docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
Testing docker-compose -f docker-compose.yml -f docker-compose.test.yml up
CI/CD or custom Add more files as needed with -f flags

🧠 Best Practices

Keep base file clean
Only include what’s common across all environments in docker-compose.yml.

Use overrides for customization
Put dev-specific things like volumes, ports, or extra services in override.yml.

Use version control wisely
Don’t commit sensitive overrides (like secrets) to Git.

Name your files clearly
Examples: docker-compose.dev.yml, docker-compose.ci.yml, docker-compose.staging.yml

Use .env files
Environment variables can be shared across Compose files using .env.


✨ Bonus Tip: Compose File Merging Rules

Docker Compose merges:

  • Services: Later files can override or add configs to existing services.
  • Volumes/Networks: New ones are added.
  • Configs/Secrets: Later files can redefine them.

️ Note: It doesn’t deeply merge arrays like command. These get replaced, not merged.


📚 Summary

Feature Benefit
Multiple Compose files Modular and DRY configurations
Environment-specific setups Easy switching between dev, test, and prod
Layered config system Avoids duplication and encourages reuse
Great for teams Devs and ops can maintain different layers

✅ Final Thoughts

Using multiple Docker Compose files makes your project flexible, scalable, and easier to manage, especially as your app grows.

Whether you're just developing locally, running tests in CI, or deploying to production — this is one of the simplest ways to keep your Docker configurations clean and organized.

Try it out and level up your Docker Compose game! 

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts