Reputation: 10608
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"
Upvotes: 41
Views: 31316
Reputation: 788
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
Upvotes: 40
Reputation: 1954
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.
Upvotes: 5
Reputation: 38962
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"
Upvotes: 9