It is a common pattern to define a base Compose file, and then define Compose files for different environments with a few small changes.
It is currently possible to extend single services, but it is very verbose to include a large number of services and make a small change to one of them (for example, setting RAILS_ENV=production
).
It should be possible to extend a Compose file with a complete set of services from another Compose file. All of those services will be copied into the Compose file, as if you were extending each of the services individually:
This is an intentionally simple first step, and I am intentionally not defining a syntax so we can discuss.
Design questions:
Related issues / suggested designs: https://github.com/docker/compose/issues/318 #1380 dcao-merge
+100
@bfirsh Let's assume a dev has a Compose file comp-dev.yml
and op has a different one comp-op.yml
, will be possible to run compose has:
docker-compose --extends op-comp.yml -f comp-dev.yml up
?
If one config depends on another, I would expect that dependency to be declared as part of the contents of the file, instead of a command line argument.
It doesn't, it belongs to the operator. This way, the operator only needs to have its own compose file for its own infrastructure. Thus, for 10000 developers with 10000 different compose files, the single operator could easily override all options the he intended on any developer's compose file as:
for file in *-dev.yml; do
docker-compose --extends op-comp.yml -f $file up -d
done
After some discussion, @dnephin and I came up with the following:
If you could pass the -f FILE
flag multiple times, that would allow you to apply arbitrarily many overrides:
$ docker-compose -f docker-compose.yml -f docker-compose.overrides.yml up
docker-compose.yml
with just the base configuration, plus a dev-specific file with overrides, that's a lot of typing, and users are going to have a terrible time.So there should be a sensible default: if docker-compose.overrides.yml
exists, we apply it as if the user had typed the full command above; if not, we behave as we currently do (i.e. as if they'd just typed docker-compose -f docker-compose.yml up
).
docker-compose
should explicitly pass the set of files in:```
# don't apply any overrides
$ docker-compose -f docker-compose.yml up
# apply production overrides
$ docker-compose -f docker-compose.yml -f docker-compose.production.yml up
```
This caters to the use case of wanting to configure an app for multiple environments: put the core stuff in docker-compose.yml
, the development overrides in docker-compose.overrides.yml
, and any other environment-specific overrides in other files (e.g. docker-compose.production.yml
).
It also caters to the use case of wanting to distribute an app's code with sensible defaults, but allowing people to override it when running it locally (for which one solution has already been proposed in #1999):
docker-compose.yml
docker-compose.overrides.yml
to .gitignore
docker-compose.overrides.yml
and override stuff locally if they want toOne limitation is that it can't currently serve _both_ use cases at once.
I agree with @dnephin ,But I guess that both of the solutions are good.
The import
inside the file is better _for me_ because it will just keep my configuration more DRY and will not _force_ me change my current deployment process.
Most helpful comment
I agree with @dnephin ,But I guess that both of the solutions are good.
The
import
inside the file is better _for me_ because it will just keep my configuration more DRY and will not _force_ me change my current deployment process.