Dockerfile에서 환경 변수 값 가져 오기


254

루비 앱용 컨테이너를 만들고 있습니다. 내 앱의 구성은 환경 변수 ( dotenv 와 함께 앱 내부에로드 )에 포함되어 있습니다.

이러한 구성 변수 중 하나는 내부적으로 링크를 만드는 데 사용되는 앱의 공용 IP입니다. 컨테이너 내부 에서이 IP를 127.0.0.1로 가리키는 dnsmasq 항목을 추가해야하므로 컨테이너화되지 않은 것처럼 앱의 링크를 가져올 수 있습니다.

따라서 ENVDockerfile에서 환경 변수를 컨테이너에 전달하는 in 을 설정하려고합니다 .

몇 가지 시도했습니다.

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

모든 것은 환경 변수 값 대신 "REQUEST_DOMAIN"문자열을 전달합니다. 호스트 시스템에서 컨테이너로 환경 변수 값을 전달하는 방법이 있습니까?

답변:


392

이 목적을 위해 Dockerfile 에서 ARG지시문 을 사용해야합니다 .

ARG명령은 사용자가 --build-arg <varname>=<value>플래그를 사용하여 docker build 명령을 사용하여 빌드시 빌더에 전달할 수있는 변수를 정의합니다 .

따라서 Dockerfile 에는 다음 줄이 있습니다.

ARG request_domain

또는 기본값을 선호하는 경우 :

ARG request_domain=127.0.0.1

이제 Dockerfile 내에서이 변수를 참조 할 수 있습니다.

ENV request_domain=$request_domain

그런 다음 컨테이너를 다음과 같이 빌드합니다.

$ docker build --build-arg request_domain=mydomain Dockerfile


참고 1 :ARG Dockerfile에서를 참조 했지만에서 제외 하면 이미지가 빌드되지 않습니다 --build-arg.

참고 2 : 사용자가 Dockerfile에 정의되지 않은 빌드 인수를 지정하면 빌드가 경고를 출력합니다.

[경고] 하나 이상의 빌드 인수 [foo]가 사용되지 않았습니다.


12
ARG는 docker v1.9부터 사용할 수 있습니다.
Synesso

이것은 docker repo에서 원격으로 빌드되도록 지원됩니까?
James Lin

4
Your image will not build if you have referenced an ARG in your Dockerfile but excluded it in --build-arg당신은 잘못. --build-arg 없이도 참조를 사용하여 이미지를 빌드 할 수 있습니다. 또한 빌드 인수의 기본값을 설정할 수 있습니다.
ALex_hha

1
ENV 라인의 목적은 무엇입니까? 나를 위해 --build-arg + ARG로 충분했습니다.
Phil

3
ARG는 후속 명령에서 dockerfile 내부에서 사용할 변수를 정의합니다. ENV는 컨테이너에 전달되는 환경 변수를 정의합니다.
herm

56

그래서 당신은 할 수 있습니다 : cat Dockerfile | envsubst | docker build -t my-target -

그런 다음 다음과 같은 Dockerfile을 사용하십시오.

ENV MY_ENV_VAR $MY_ENV_VAR

특수 문자에 문제가있을 수 있지만 적어도 대부분의 경우 작동합니다.


13
Dockerfile이 포함 된 디렉토리에서 파일을 추가 해야하는 경우 작동하지 않는 것 같습니다.
Tom Hennen

2
아주 좋은 해결책! Mac envsubst에서는의 일부로 얻을 수 있습니다 brew install gettext. 그러나 BSD 빌드 시스템과의 충돌 가능성 때문에 "keg-only"이며 아무런 영향도 없습니다. 그러나 ln -s /usr/local/Cellar/gettext/*/bin/envsubst /usr/local/bin/하나의 명령을 PATH에 추가하는 것이 안전합니다 . (실제로 우려되는 라이브러리입니다.) 또는 해당 /usr/local/Cellar/gettext/*/bin/envsubst위치 에서 사용할 수 있습니다
Bruno Bronosky

1
@TomHennen의 의견을 명확히하기 위해 Dockerfile을 파이핑하는 docker build -것은 특히 env var 대체에 관계없이 Dockerfile에서 상대 경로를 참조 할 때 작동하지 않는 것입니다.
superEb

4
당신이 경우 TomHennen의 코멘트 @ 다시는 않습니다 당신의 Dockerfile에 COPY 같은 상황에 따라 명령을 사용하려면 당신은 항상 임시 파일에 envsubst의 출력을 리디렉션 다음에 있음을 공급할 수 docker build대신. 예 : cat Dockerfile | envsubst > DockerfileWithEnvVars다음 docker build -t my-target -f DockerfileWithEnvVars ., 다음rm DockerfileWithEnvVars
스나크

또는 moreutils 패키지의 스폰지를 사용할 수 있습니다envsubst < Dockerfile | sponge Dockerfile
ALex_hha

19

또는 과 envsubst같은 명령을 사용 하지 않고 중간 파일을 사용하지 않고 Bash의 프로세스 대체를 사용하는 대안 이 있습니다 .COPYADD

docker build -f <(envsubst < Dockerfile) -t my-target .

3
불행히도 그것은 작동하지 않는 것 같습니다 (Docker 17.09), 오류가 발생합니다unable to prepare context: the Dockerfile (/dev/fd/63) must be within the build context
Alexander Klimetschek

11

런타임에 작성한 파일에서 환경 변수를로드하십시오.

export MYVAR="my_var_outside"
cat > build/env.sh <<EOF
MYVAR=${MYVAR}
EOF

... 그리고 Dockerfile에서

ADD build /build
RUN /build/test.sh

여기서 test.sh는 env.sh에서 MYVAR을로드합니다.

#!/bin/bash
. /build/env.sh
echo $MYVAR > /tmp/testfile

4

Dockerfile에서 모든 환경 변수 ($ ExampleEnvVar)를 찾아 바꾸려면 다음과 같이하십시오.

envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -


여기에 가장 좋은 대답은 그것을 기반으로 할 수 있다는 것입니다. 라인이 환경 변수를 사용하는 envsubst < ./Dockerfile | docker build -squash -t ${DOCKIMG}:${VERSION} . -f -FROM.
mikequentel

-6

-e컨테이너에 환경 변수를 전달하기위한 키를 추가하십시오 . 예:

$ MYSQLHOSTIP=$(sudo docker inspect -format="{{ .NetworkSettings.IPAddress }}" $MYSQL_CONRAINER_ID)
$ sudo docker run -e DBIP=$MYSQLHOSTIP -i -t myimage /bin/bash

root@87f235949a13:/# echo $DBIP
172.17.0.2

6
Damien은 이미지를 만들려고합니다. -e는 대신 run 명령과 함께 작동합니다.
Andres Restrepo 4
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.