How to use environment variables in docker compose

后端 未结 13 736
孤街浪徒
孤街浪徒 2020-11-28 01:02

I would like to be able to use env variables inside docker-compose.yml, with values passed in at the time of docker-compose up. This is the example.

I am

相关标签:
13条回答
  • 2020-11-28 01:12

    I have a simple bash script I created for this it just means running it on your file before use: https://github.com/antonosmond/subber

    Basically just create your compose file using double curly braces to denote environment variables e.g:

    app:
        build: "{{APP_PATH}}"
    ports:
        - "{{APP_PORT_MAP}}"
    

    Anything in double curly braces will be replaced with the environment variable of the same name so if I had the following environment variables set:

    APP_PATH=~/my_app/build
    APP_PORT_MAP=5000:5000
    

    on running subber docker-compose.yml the resulting file would look like:

    app:
        build: "~/my_app/build"
    ports:
        - "5000:5000"
    
    0 讨论(0)
  • 2020-11-28 01:14

    The DOCKER solution:

    It looks like docker-compose 1.5+ has enabled variables substitution: https://github.com/docker/compose/releases

    The latest Docker Compose allows you to access environment variables from your compose file. So you can source your environment variables, then run Compose like so:

    set -a
    source .my-env
    docker-compose up -d
    

    Then you can reference the variables in docker-compose.yml using ${VARIABLE}, like so:

    db:
      image: "postgres:${POSTGRES_VERSION}"
    

    And here is more info from the docs, taken here: https://docs.docker.com/compose/compose-file/#variable-substitution

    When you run docker-compose up with this configuration, Compose looks for the POSTGRES_VERSION environment variable in the shell and substitutes its value in. For this example, Compose resolves the image to postgres:9.3 before running the configuration.

    If an environment variable is not set, Compose substitutes with an empty string. In the example above, if POSTGRES_VERSION is not set, the value for the image option is postgres:.

    Both $VARIABLE and ${VARIABLE} syntax are supported. Extended shell-style features, such as ${VARIABLE-default} and ${VARIABLE/foo/bar}, are not supported.

    If you need to put a literal dollar sign in a configuration value, use a double dollar sign ($$).

    And I believe this feature was added in this pull request: https://github.com/docker/compose/pull/1765

    The BASH solution:

    I notice folks have issues with Docker's environment variables support. Instead of dealing with environment variables in Docker, let's go back to basics, like bash! Here is a more flexible method using a bash script and a .env file.

    An example .env file:

    EXAMPLE_URL=http://example.com
    # Note that the variable below is commented out and will not be used:
    # EXAMPLE_URL=http://example2.com 
    SECRET_KEY=ABDFWEDFSADFWWEFSFSDFM
    
    # You can even define the compose file in an env variable like so:
    COMPOSE_CONFIG=my-compose-file.yml
    # You can define other compose files, and just comment them out
    # when not needed:
    # COMPOSE_CONFIG=another-compose-file.yml
    

    then run this bash script in the same directory, which should deploy everything properly:

    #!/bin/bash
    
    docker rm -f `docker ps -aq -f name=myproject_*`
    set -a
    source .env
    cat ${COMPOSE_CONFIG} | envsubst | docker-compose -f - -p "myproject" up -d
    

    Just reference your env variables in your compose file with the usual bash syntax (ie ${SECRET_KEY} to insert the SECRET_KEY from the .env file).

    Note the COMPOSE_CONFIG is defined in my .env file and used in my bash script, but you can easily just replace {$COMPOSE_CONFIG} with the my-compose-file.yml in the bash script.

    Also note that I labeled this deployment by naming all of my containers with the "myproject" prefix. You can use any name you want, but it helps identify your containers so you can easily reference them later. Assuming that your containers are stateless, as they should be, this script will quickly remove and redeploy your containers according to your .env file params and your compose YAML file.

    Update Since this answer seems pretty popular, I wrote a blog post that describes my Docker deployment workflow in more depth: http://lukeswart.net/2016/03/lets-deploy-part-1/ This might be helpful when you add more complexity to a deployment configuration, like nginx configs, LetsEncrypt certs, and linked containers.

    0 讨论(0)
  • 2020-11-28 01:15

    When using environment variables for volumes you need:

    1. create .env file in the same folder which contains docker-compose.yaml file

    2. declare variable in the .env file:

      HOSTNAME=your_hostname
      
    3. Change $hostname to ${HOSTNAME} at docker-compose.yaml file

      proxy:
        hostname: ${HOSTNAME}
        volumes:
          - /mnt/data/logs/${HOSTNAME}:/logs
          - /mnt/data/${HOSTNAME}:/data
      

    Of course you can do that dynamically on each build like:

    echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up
    
    0 讨论(0)
  • 2020-11-28 01:17
    env SOME_VAR="I am some var" OTHER_VAR="I am other var" docker stack deploy -c docker-compose.yml
    

    Use the version 3.6 :

    version: "3.6"
    services:
      one:
        image: "nginx:alpine"
        environment:
          foo: "bar"
          SOME_VAR:
          baz: "${OTHER_VAR}"
        labels:
          some-label: "$SOME_VAR"
      two:
        image: "nginx:alpine"
        environment:
          hello: "world"
          world: "${SOME_VAR}"
        labels:
          some-label: "$OTHER_VAR"
    

    I got it form this link https://github.com/docker/cli/issues/939

    0 讨论(0)
  • 2020-11-28 01:18
    1. Create a template.yml, which is your docker-compose.yml with environment variable.
    2. Suppose your environment variables are in a file 'env.sh'
    3. Put the below piece of code in a sh file and run it.

    source env.sh; rm -rf docker-compose.yml; envsubst < "template.yml" > "docker-compose.yml";

    A new file docker-compose.yml will be generated with the correct values of environment variables.

    Sample template.yml file:

    oracledb:
            image: ${ORACLE_DB_IMAGE}
            privileged: true
            cpuset: "0"
            ports:
                    - "${ORACLE_DB_PORT}:${ORACLE_DB_PORT}"
            command: /bin/sh -c "chmod 777 /tmp/start; /tmp/start"
            container_name: ${ORACLE_DB_CONTAINER_NAME}
    

    Sample env.sh file:

    #!/bin/bash 
    export ORACLE_DB_IMAGE=<image-name> 
    export ORACLE_DB_PORT=<port to be exposed> 
    export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER
    
    0 讨论(0)
  • 2020-11-28 01:28

    You cannot ... yet. But this is an alternative, think like a docker-composer.yml generator:

    https://gist.github.com/Vad1mo/9ab63f28239515d4dafd

    Basically a shell script that will replace your variables. Also you can use Grunt task to build your docker compose file at the end of your CI process.

    0 讨论(0)
提交回复
热议问题