Programming

docker compose에서 환경 변수를 사용하는 방법

procodes 2020. 5. 25. 22:42
반응형

docker compose에서 환경 변수를 사용하는 방법


docker-compose.yml에서 docker-compose up시 전달 된 값으로 env 변수를 사용할 수 있기를 원합니다. 이것은 예입니다. 나는 오늘 자신의 스크립트를 감싸는 기본 docker run 명령 으로이 작업을 수행하고 있습니다. 그러한 bash 래퍼없이 compose로 달성 할 수있는 방법이 있습니까?

proxy:
  hostname: $hostname
  volumes:
    - /mnt/data/logs/$hostname:/logs
    - /mnt/data/$hostname:/data

  1. with 환경 변수 template.yml인을 만듭니다 docker-compose.yml.
  2. 환경 변수가 'env.sh'파일에 있다고 가정하십시오.
  3. 아래 코드를 sh 파일에 넣고 실행하십시오.

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

docker-compose.yml올바른 환경 변수 값으로 새 파일 이 생성됩니다.

샘플 template.yml 파일 :

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}

샘플 env.sh 파일 :

#!/bin/bash 
export ORACLE_DB_IMAGE=<image-name> 
export ORACLE_DB_PORT=<port to be exposed> 
export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER

DOCKER 솔루션 :

docker-compose 1.5 이상에서 변수 대체를 활성화 한 것 같습니다 : https://github.com/docker/compose/releases

최신 Docker Compose를 사용하면 작성 파일에서 환경 변수에 액세스 할 수 있습니다. 따라서 환경 변수를 소싱 한 다음 Compose를 다음과 같이 실행할 수 있습니다.

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

그런 다음 $ {VARIABLE}을 사용하여 docker-compose.yml에서 변수를 참조 할 수 있습니다.

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

그리고 여기 문서에서 가져온 더 많은 정보가 있습니다 : https://docs.docker.com/compose/compose-file/#variable-substitution

이 구성으로 docker-compose를 실행하면 Compose는 셸에서 POSTGRES_VERSION 환경 변수를 찾아 그 값을 대체합니다.이 예에서 Compose는 구성을 실행하기 전에 이미지를 postgres : 9.3으로 해석합니다.

환경 변수가 설정되지 않은 경우 작성은 빈 문자열로 대체됩니다. 위의 예에서 POSTGRES_VERSION이 설정되지 않은 경우 이미지 옵션의 값은 postgres :입니다.

$ VARIABLE 및 $ {VARIABLE} 구문이 모두 지원됩니다. $ {VARIABLE-default} 및 $ {VARIABLE / foo / bar}와 같은 확장 된 셸 스타일 기능은 지원되지 않습니다.

구성 값에 리터럴 달러 기호를 넣어야하는 경우 더블 달러 기호 ($$)를 사용하십시오.

그리고이 풀 요청 에이 기능이 추가되었다고 생각합니다 : https://github.com/docker/compose/pull/1765

BASH 솔루션 :

Docker의 환경 변수 지원에 문제가있는 사람들이 있습니다. Docker에서 환경 변수를 처리하는 대신 bash와 같은 기본으로 돌아가 봅시다! 다음은 bash 스크립트와 .env파일을 사용하는보다 유연한 방법 입니다.

.env 파일 예 :

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

그런 다음이 bash 스크립트를 동일한 디렉토리에서 실행하십시오.이 디렉토리는 모든 것을 올바르게 배치해야합니다.

#!/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

일반적인 bash 구문을 사용하여 작성 파일에서 env 변수를 참조하십시오 (예 : 파일 에서 ${SECRET_KEY}삽입 ).SECRET_KEY.env

(가) 주 COMPOSE_CONFIG내에서 정의 .env파일 내 bash는 스크립트에 사용되는,하지만 당신은 그냥 쉽게 교체 할 수 있습니다 {$COMPOSE_CONFIG}my-compose-file.ymlbash는 스크립트.

또한 모든 컨테이너의 이름을 "myproject"접두어로 지정하여이 배포에 레이블을 지정했습니다. 원하는 이름을 사용할 수 있지만 나중에 쉽게 참조 할 수 있도록 컨테이너를 식별하는 데 도움이됩니다. 컨테이너가 상태가없는 것으로 가정하면이 스크립트는 .env 파일 매개 변수 및 작성 YAML 파일에 따라 컨테이너를 신속하게 제거하고 재배치합니다.

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.


It seems that docker-compose has native support now for default environment variables in file.

all you need to do is declare your variables in a file named .env and they will be available in docker-compose.yml.

For example, for .env file with contents:

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

You could access your variable inside docker-compose.yml or forward them into the container:

my-service:
  image: ${IMAGE_NAME}
  environment:
    MY_SECRET_KEY: ${MY_SECRET_KEY}

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

The following is applicable for docker-compose 3.x Set environment variables inside the container

method - 1 Straight method

web:
  environment:
    - DEBUG=1
      POSTGRES_PASSWORD: 'postgres'
      POSTGRES_USER: 'postgres'

method - 2 The “.env” file

Create a .env file in the same location as the docker-compose.yml

$ cat .env
TAG=v1.5
POSTGRES_PASSWORD: 'postgres'

and your compose file will be like

$ cat docker-compose.yml
version: '3'
services:
  web:
    image: "webapp:${TAG}"
    postgres_password: "${POSTGRES_PASSWORD}"

source


The best way is to specify environment variables outside the docker-compose.yml file. You can use env_file setting, and define your environment file within the same line. Then doing a docker-compose up again should recreate the containers with the new environment variables.

Here is how my docker-compose.yml looks like:

services:
  web:
    env_file: variables.env

Note: docker-compose expects each line in an env file to be in VAR=VAL format. Avoid using export inside the .env file. Also, the .env file should be placed in the folder where the docker-compose command is executed.


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.


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"

As far as I know, this is a work-in-progress. They want to do it, but it's not released yet. See 1377 (the "new" 495 that was mentioned by @Andy).

I ended up implementing the "generate .yml as part of CI" approach as proposed by @Thomas.


add env to .env file

Such as

VERSION=1.0.0

then save it to deploy.sh

INPUTFILE=docker-compose.yml
RESULT_NAME=docker-compose.product.yml
NAME=test

prepare() {
        local inFile=$(pwd)/$INPUTFILE
        local outFile=$(pwd)/$RESULT_NAME
        cp $inFile $outFile
        while read -r line; do
            OLD_IFS="$IFS"
            IFS="="
            pair=($line)
            IFS="$OLD_IFS"
               sed -i -e "s/\${${pair[0]}}/${pair[1]}/g" $outFile
            done <.env
     }

deploy() {
        docker stack deploy -c $outFile $NAME
}


prepare
deploy

Use .env file to define dynamic values in docker-compse.yml. Be it port or any other value.

Sample docker-compose:

testcore.web:
       image: xxxxxxxxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/testcore:latest
       volumes: 
            - c:/logs:c:/logs
       ports:
            - ${TEST_CORE_PORT}:80
       environment:
            - CONSUL_URL=http://${CONSUL_IP}:8500 
            - HOST=${HOST_ADDRESS}:${TEST_CORE_PORT}

Inside .env file you can define the value of these variables:

CONSUL_IP=172.31.28.151
HOST_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002

참고URL : https://stackoverflow.com/questions/29377853/how-to-use-environment-variables-in-docker-compose

반응형