I created a service for docker-compose 3 that uses many environment variables:
version: "3"
services:
myservice:
build:
context: ./myservice
command: ./something
environment:
VAR1: "val1"
VAR2: "val2"
VAR3: "val3"
Now I want to add a service that uses the same environment variable values, except for VAL1
, and that has a different command:
myotherservice:
build:
context: ./myservice
command: ./somethingelse
environment:
VAR1: "val1-bis"
VAR2: "val2"
VAR3: "val3"
Is there any way to avoid the duplication of environment variables in the docker-compose.yml
file? In docker-compose 2, it was possible to use the extends
keyword but this is no longer the case in docker-compose 3.
EDIT: In October 2017, extension fields were added to the docker-compose 3.4 syntax: https://docs.docker.com/compose/compose-file/#extension-fields This is the right way to go:
version: "3"
x-env:
&default-env
VAR1: "val1"
VAR2: "val2"
VAR3: "val3"
services:
myservice:
build:
context: ./myservice
command: ./something
environment: *default-env
myotherservice:
build:
context: ./myservice
command: ./somethingelse
environment:
<< : *default-env
VAR1: "val1-bis"
The Compose file is a YAML file defining services, networks and volumes. The default path for a Compose file is ./docker-compose.yml . Tip: You can use either a .yml or .yaml extension for this file. They both work.
depends_on is a Docker Compose keyword to set the order in which services must start and stop. For example, suppose we want our web application, which we'll build as a web-app image, to start after our Postgres container.
This is very easy with YAML:
version: "3" services: myservice: &myservice build: context: ./myservice command: ./something environment: &myservice_environment VAR1: "val1" VAR2: "val2" VAR3: "val3" myotherservice: <<: *myservice environment: <<: *myservice_environment VAR1: "val1-bis"
See the doc regarding extension-fields
You can extract common environment variables to a env file.
Thereafter you can use the env_file
configuration option in your compose file.
-> cat common.env VAR2=val2 VAR3=val3
You can still pass/overwrite environment variables other than those specified in common.env
using the environment
configuration option.
myotherservice: build: context: ./myservice command: ./somethingelse env_file: ./common.env environment: VAR1: "val1-bis"
Watch out when using the YAML merge type as suggested by the OP and the extension fields documentation.
The merge type works on dictionaries/maps only, but not on arrays/lists. Fortunately, the environment section can be a dictionary or an array. So the OP's example with the environment section works.
However, the volumes section must be an array, and as such the merging will not work there. The need for an array is not mentioned in the docs, but a quick local test reveals ...volumes contains an invalid type, it should be an array
with docker version 18.09.2
In conclusion, anchors, aliases and merge types can help you in many cases, but they do work differently than the merging of multiple compose files via docker-compose -f file1 file2
, and different than the extends directive in compose 2. There, merging of lists works as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With