45

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.

AdrieanKhisbe
  • 3,719
  • 7
  • 35
  • 45
Reto Gmür
  • 2,287
  • 1
  • 18
  • 24

3 Answers3

29

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

José Luis
  • 3,353
  • 4
  • 27
  • 35
  • Please note there is a known Docker-compose [issue](https://github.com/docker/compose/issues/3874) so paths are not being forwarded correctly in case of having several folders – The Godfather Aug 18 '18 at 16:23
24

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.

Bono
  • 4,649
  • 6
  • 46
  • 76
Justin Niessner
  • 236,029
  • 38
  • 403
  • 530
  • Thanks. However this still requires to list all 10 services in the `swap-backen-compose.yaml`file and if I add a new service I have to edit bot files. I was looking for a way to inherit or include the whole compose. – Reto Gmür Oct 29 '15 at 07:55
  • 1
    @RetoGmür - I just went through the same thing. Unfortunately there isn't currently a way to extend an entire Docker Compose configuration file. – Justin Niessner Oct 29 '15 at 08:08
  • I think you'll be interested in https://github.com/docker/compose/pull/2051 which is available in the latest RC release https://github.com/docker/compose/releases/tag/1.5.0rc2 – dnephin Oct 29 '15 at 21:20
  • 25
    Note `extends` command is deprecated and was completely [removed](https://docs.docker.com/compose/extends/#extending-services) in Compose v3.x – The Godfather Aug 18 '18 at 18:21
4

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.
Zach Valenta
  • 1,488
  • 1
  • 17
  • 34
  • 1
    Is it necessary to repeat the `version` in inheritors or will that be taken over from the base? – theberzi Apr 26 '22 at 10:34
  • I don't know for sure but suspect "no" given that VERSION itself is now apparently "defined by the specification for backward compatibility but is only informative". https://docs.docker.com/compose/compose-file/#version-top-level-element – Zach Valenta Apr 26 '22 at 13:12
  • 1
    I had a chance to test it and indeed I confirm there's no need to repeat the version in inheritors. :) – theberzi Apr 27 '22 at 07:40
  • Nice, just updated my answer to reflect that. – Zach Valenta Apr 27 '22 at 14:47