55

The best way to start our application is by using a docker compose we provide. The docker-compose starts all the services with the right configuration.

Now we would like to provide a docker-compose where the application runs with a different backend. In this compose 8 out 10 services are the same and 2 are different.

How to achieve this without code duplication? I see that a service can extend a service from another docker-compose file, however this would still require to list all the 10 services in both files.

3 Answers 3

37

With docker-compose 1.6 this should be possible.

Create a docker-compose.yml with your common services:

service01:
  image: image01
  links:
    - service02

service02:
  image: image02

And a second file, docker-compose.prod.yml with your unique services:

service03:
  image: image03
  links:
    - service02

Now you can start service 01, 02 and 03 with this command:

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

For more information, see the official documentation: https://docs.docker.com/compose/extends/#multiple-compose-files

Sign up to request clarification or add additional context in comments.

Comments

34

The easiest way to achieve this is to create a second compose file. In the second file, you can use the extend feature of Docker Compose which allows you to "inherit" services from another file: https://docs.docker.com/compose/extends/

Assuming your original file is docker-compose.yaml, you could create a swap-backend-compose.yaml:

service-one:
  extends:
    file: docker-compose.yaml
    service: service-one

service-two:
  extends:
    file: docker-compose.yaml
    service: service-two
  environment:
    - BACKEND=some_other_value

...and so on.

Comments

15

As noted in the comments, Version 3 deprecates the extends keyword, so here's a minimal example without it:

# BASE - docker-compose.base.yml
version: "3"
services:
  api:
    build: .

# DEV - docker-compose.dev.yml
services:
  api:
    command: npm run dev

# PROD - docker-compose.prod.yml
services:
  api:
    command: npm run prod

A few notes:

  • per-environment files (.dev.yml, .prod.yml) can inherit, add to and replace config options from the base file (.base.yml)
  • in this example, the per-env files 1) inherit the build option 2) add their own command option
  • the base file is typically named docker-compose.yml; I've added .base here just to highlight the inheritance aspect and because I favor more explicit names; keep in mind docker-compose looks for docker-compose.yml and docker-compose.override.yml by default.

4 Comments

And you would start your prod version like this: docker compose -f docker-compose.yml -f docker-compose.prod.yml up
Is there a way to remove a service with this technique? For instance, remove your api service in dev but keep it in prod.
Good question! If you find an answer, might be worth posting as a standalone Q&A.
extends is still supported in v4, it seems: docs.docker.com/reference/compose-file/services/#extends

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.