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


217

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

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

2
다른 옵션은 다음을 참조하십시오 : docs.docker.com/compose/environment-variables
Massood Khaari

2
작곡의 마지막 버전에서 해결되었으므로 예제는 그대로 작동합니다. 변수 대체에 대해서는 docs.docker.com/compose/compose-file/#variable-substitution을 확인하십시오 .
natbusa

1
docker-app를 잊지 마십시오 (2018 년 6 월부터) : stackoverflow.com/a/51007138/6309
VonC

답변:


93
  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

@Meet "BASH 솔루션"에서 아래의 답변을 조금 더 자세히 살펴보십시오.
modulitos

7
아직도 더 나은 해결책이 없습니까?
lvthillo

13
왜 파일을 재귀 적으로 삭제 하시겠습니까? (rm -rf docker-compose.yml)
moritzschaefer

@ lorenzvth7 아래 답변을 좀 더 철저하게 확인할 수 있습니다. stackoverflow.com/a/33186458/1884158
modulitos

5
-1이 솔루션은 고정 표시기-작성 새로운 능력에 따라 일을 복잡하게 업데이트되어야한다 docs.docker.com/compose/environment-variables/...
Efrat 레비

240

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 파일에 따라 컨테이너를 빠르게 제거하고 재배치합니다.

업데이트이 답변은 꽤 인기가있는 것으로 보이므로 Docker 배포 워크 플로에 대해보다 자세하게 설명하는 블로그 게시물을 작성했습니다. http://lukeswart.net/2016/03/lets-deploy-part-1/ 추가하면 도움이 될 수 있습니다 nginx 구성, LetsEncrypt 인증서 및 연결된 컨테이너와 같은 배포 구성에 대한 더 복잡한.


2
grep foo file.text대신에 간단하게 할 수 있습니다 cat file.text | grep foo. 내 경우에는 export $(grep "^[^#]" .config | xargs) && cat docker-compose.yml | envsubst.
Jorge Lavín

"사람들이 Docker의 환경 변수 지원에 문제가 있음을 알게되었습니다"– 티켓에 대한 세부 정보 나 링크가 있습니까?
tleyden

죄송합니다. 발생한 특정 문제를 기록하지 않았으며 너무 오래 전 (~ 6 개월) 문제가 여전히 관련이 있는지 잘 모르겠습니다. 그러나 Docker 환경 변수 지원의 일부 기능은 버그가 많았으며 여러 사용자 가보고했습니다. 나는 지금 훨씬 나아 졌다고 믿는다. 그러나 배포 구성이 상당히 복잡해지면 bash를 사용하여 구성 논리를 처리하고 컨테이너 오케스트레이션을 위해 Docker Compose를 처리하여 모듈화를 선호합니다.
modulitos

8
PSA :이 기능은 에서만 작동하고에서는 작동docker-compose up 하지 않습니다 docker-compose run.
Kriegslustig

5
이 솔루션이 docs.docker.com/compose/compose-file/#envfile 당신이에서 환경 변수를 추가 어디에 사용하는 것이 .env아래는 env_file. 다음을 docker-compose.yml사용하여 변수를 참조 할 수 있습니다.${VARIABLE}
musale

112

docker-compose는 이제 file의 기본 환경 변수기본적으로 지원하는 것으로 보입니다 .

이름이 지정된 파일로 변수를 선언하기 .env만하면 docker-compose.yml에서 변수를 사용할 수 있습니다.

예를 들어, .env내용이있는 파일의 경우 :

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

변수 내부에 액세스 docker-compose.yml하거나 컨테이너에 전달할 수 있습니다.

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

4
이것이 최고의 솔루션입니다!
Ladenkov Vladislav

4
이것은 나를 위해 일했다. 왜 그런지 모르겠지만 파일 이름은 그대로 있어야합니다. .env예를 들어 config.env저에게 효과적이지 않았습니다.
HBat

1
@HBat "." 숨겨진 파일을 의미한다 -이 지역의 설정 파일에 대한 일반적인 절차는
제레미 HAJEK

2
최고의 솔루션. / etc / environment 소품을 추가하고 .env를 사용하여 환경으로 사용할 수 있습니다. 더 안전합니다.
Chinthaka Dinadasa 2018 년

24

다음은 컨테이너 내부의 docker-compose 3.x Set 환경 변수에 적용됩니다.

방법-1 직선 방법

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

방법-2 “.env”파일

docker-compose.yml과 동일한 위치에 .env 파일을 만듭니다.

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

작성 파일은

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

출처


2
방법 1의 전체 예를보고 싶습니다.이 작업을 수행 할 수 없어서 .env 파일 (정상 작동)을 사용했습니다.
BobHy

20

볼륨에 환경 변수를 사용하는 경우 다음이 필요합니다.

  1. 만들 .env의 들어있는 동일한 폴더에 파일을 docker-compose.yaml 파일을

  2. .env파일 에서 변수를 선언 하십시오.

    HOSTNAME=your_hostname
    
  3. 변경 $hostname하기 ${HOSTNAME}에서 docker-compose.yaml 파일

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

물론 각 빌드에서 다음과 같이 동적으로 수행 할 수 있습니다.

echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up

9
문서에 따르면 :The .env file feature only works when you use the docker-compose up command and does not work with docker stack deploy.
James Gentes

19

가장 좋은 방법은 docker-compose.yml파일 외부에 환경 변수를 지정하는 것 입니다. env_file설정 을 사용 하고 동일한 줄에서 환경 파일을 정의 할 수 있습니다. 그런 다음 docker-compose up을 다시 수행하여 새로운 환경 변수로 컨테이너를 다시 만들어야합니다.

내 docker-compose.yml의 모양은 다음과 같습니다.

services:
  web:
    env_file: variables.env

참고 : docker-compose는 env 파일의 각 줄이 VAR=VAL형식 이어야 합니다. 파일 export내부에서 사용하지 마십시오 .env. 또한 .env파일은 docker-compose 명령이 실행되는 폴더에 있어야합니다.


2
실제로 가장 좋은 방법
Dany

아니. Docker 컨테이너 내에서 환경 변수를 자동으로 사용할 수는 없습니다. 여전히 환경 섹션에서이를 명시 적으로 언급해야합니다.
kta

6

당신은 아직 ... 할 수 없습니다. 그러나 이것은 대안입니다. docker-composer.yml 생성기처럼 생각하십시오.

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

기본적으로 변수를 대체 할 쉘 스크립트입니다. 또한 Grunt 작업을 사용하여 CI 프로세스가 끝나면 docker compose 파일을 작성할 수 있습니다.


4

나는 이것을 위해 만든 간단한 bash 스크립트를 가지고있다. 사용하기 전에 파일에서 실행한다는 것을 의미한다 : https://github.com/antonosmond/subber

기본적으로 환경 변수를 나타내는 이중 중괄호를 사용하여 작성 파일을 작성하십시오. 예 :

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

이중 중괄호로 묶인 것은 다음과 같은 환경 변수가 설정된 경우 동일한 이름의 환경 변수로 대체됩니다.

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

subber docker-compose.yml결과 파일 을 실행 하면 다음과 같습니다.

app:
    build: "~/my_app/build"
ports:
    - "5000:5000"

2

내가 아는 한, 이것은 진행중인 작업입니다. 그들은 그것을하고 싶지만 아직 풀리지 않았습니다. 1377 ( @Andy가 언급 한 "새로운" 495) 을 참조하십시오 .

@Thomas가 제안한대로 "CI의 일부로 .yml 생성"접근 방식을 구현했습니다.


1

.env 파일에 env 추가

와 같은

VERSION=1.0.0

그런 다음에 저장 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
    

1

.env 파일을 사용하여 docker-compse.yml에서 동적 값을 정의하십시오. 포트 또는 다른 값이어야합니다.

도커 작성 샘플 :

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}

.env 파일에서 다음 변수의 값을 정의 할 수 있습니다.

CONSUL_IP=172.31.28.151
HOST_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002

1
env SOME_VAR="I am some var" OTHER_VAR="I am other var" docker stack deploy -c docker-compose.yml

버전 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"

나는이 링크 https://github.com/docker/cli/issues/939에서 그것을 얻었다


1

1.25.4부터 docker-compose는 --env-file변수가 포함 된 파일을 지정할 수 있는 옵션 을 지원합니다 .

당신의 모습은 다음과 같습니다 :

hostname=my-host-name

그리고 명령 :

docker-compose --env-file /path/to/my-env-file config
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.