Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-using environment variables in docker-compose.yml

Is it possible to re-use environment variables that are shared among multiple containers?

The idea is to avoid duplication, as illustrated in this example:

version: '2'  services:    db:     image: example/db     ports:       - "8443:8443"      container_name: db     hostname: db     environment:       - USER_NAME = admin        - USER_PASSWORD = admin   svc:   image: example/svc   depends_on:     - db   ports:     - "9443:9443"   container_name: svc   hostname: svc   environment:     - DB_URL = https://db:8443     - DB_USER_NAME = admin     - DB_USER_PASSWORD = admin  
like image 970
Sergei Rodionov Avatar asked Mar 29 '16 12:03

Sergei Rodionov


People also ask

Can I use environment variables in docker compose file?

Substitute environment variables in Compose files. If you have multiple environment variables, you can substitute them by adding them to a default environment variable file named . env or by providing a path to your environment variables file using the --env-file command line option.

Does docker compose override environment variables?

But docker-compose does not stop at the . env and the host's current environment variables. It's cool that you can simply override values of your . env file, but this flexibility is can also be the source of nasty bugs.

How do I pass environment variables to docker containers?

With a Command Line Argument The command used to launch Docker containers, docker run , accepts ENV variables as arguments. Simply run it with the -e flag, shorthand for --env , and pass in the key=value pair: sudo docker run -e POSTGRES_USER='postgres' -e POSTGRES_PASSWORD='password' ...

How do I set an environment variable on an existing container?

To set an environment variable you should use flag -e while using docker run or docker-compose command. Environment file - If the environment variable is not overridden by docker-compose. yml, shell environment the variable then the environment file will get the precedence.


2 Answers

The extends option can be nice but it's not supported in 3.x compose files. Other ways to go are:

  1. Extension fields (compose file 3.4+)

    If you can use 3.4+ compose files, extension fields are probably the best option:

    docker-compose.yml

     version: '3.4'   x-common-variables: &common-variables    VARIABLE: some_value    ANOTHER_VARIABLE: another_value   services:    some_service:      image: someimage      environment: *common-variables     another_service:      image: anotherimage      environment:        <<: *common-variables        NON_COMMON_VARIABLE: 'non_common_value' 
  2. env_file directive

    docker-compose.yml

     version: '3.2'   services:    some_service:      image: someimage      env_file:        - 'variables.env'     another_service:      image: anotherimage      env_file:        - 'variables.env' 

    variables.env

     VARIABLE=some_value  ANOTHER_VARIABLE=another_value 
  3. .env file in project root (or variables at actual compose environment)

    Variables from .env file can be referenced in service configuration:

    docker-compose.yml

     version: '3.2'   services:    some_service:      image: someimage      environment:        - VARIABLE     another_service:      image: anotherimage      environment:        - VARIABLE        - ANOTHER_VARIABLE 

    .env

     VARIABLE=some_value  ANOTHER_VARIABLE=another_value 
like image 51
Wolphin Avatar answered Sep 27 '22 17:09

Wolphin


You can use the extends directive (available in compose 1.x and 2.x) to have multiple containers inherit the environment configuration from an underlying service description. For example, put the following in a file named base.yml:

version: '2'  services:   base:     environment:       DB_URL: https://db:8443       DB_USER_NAME: admin       DB_USER_PASSWORD: admin  

Then in your docker-compose.yml:

version: '2'  services:   container1:     image: alpine     command: sh -c "env; sleep 900"     extends:       file: base.yml       service: base    container2:     image: alpine     command: sh -c "env; sleep 900"     extends:       file: base.yml       service: base     environment:       ANOTHERVAR: this is a test 

Then inside of container1, you will see:

DB_URL=https://db:8443 DB_USER_NAME=admin DB_USER_PASSWORD=admin 

And inside of container2 you will see:

DB_URL=https://db:8443 DB_USER_NAME=admin DB_USER_PASSWORD=admin ANOTHERVAR=this is a test 

You can obviously use extends for things other than the environment directive; it's a great way to avoid duplication when using docker-compose.

like image 41
larsks Avatar answered Sep 27 '22 15:09

larsks