'Inheritance or nesting with docker compose

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.



Solution 1:[1]

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

Solution 2:[2]

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.

Solution 3:[3]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 José Luis
Solution 2 Bono
Solution 3