Dockerfile-ENV를 명령 결과로 설정


답변:


23

DarkSideF 답변에 추가로.

Dockerfile의 각 줄 / 명령은 다른 컨테이너에서 실행된다는 점에 유의해야합니다.

다음과 같이 할 수 있습니다.

RUN export bleah=$(hostname -f);echo $bleah;

이것은 단일 컨테이너에서 실행됩니다.


14
그냥 명확하게 - $bleah입니다 하지 심지어 같은 dockerfile의 다음 행에서이 RUN 명령을 외부에서 사용할 수 어디서나, 그것은 떨어져 기반으로 다른 이미지에서 혼자 할 수 있습니다. 여기 도커에서 누락 된 기능은 정말 명백합니다. 파일에 쓰고 읽는 것이 이미지에 (동적) 변수를 실제로 저장하고 이미지간에 전달하는 유일한 방법 인 것처럼 보입니다.
davnicwil

17

나는 같은 문제가 있었고 dockerfile에서 RUN 명령을 사용하여 기능의 결과로 환경 변수를 설정하는 방법을 찾았습니다.

예를 들어, Rails 앱에 SECRET_KEY_BASE를 한 번만 설정하면됩니다.

docker run  -e SECRET_KEY_BASE="$(openssl rand -hex 64)"

대신 다음과 같이 Dockerfile 문자열에 씁니다.

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

bash 로그인 후에도 루트에서 사용할 수있는 내 env 변수. 또는

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'

그런 다음 CMD 및 ENTRYPOINT 명령에서 사용할 수 있습니다.

Docker는 계층으로 캐시하고 이전에 일부 문자열을 변경하는 경우에만 변경합니다.

환경 변수를 설정하는 다른 방법 을 시도 할 수도 있습니다 .


/etc/profile.d/docker_init.sh가 여전히 문제입니까? 이 답변은 Google에서 찾을 수있는 유일한 언급이며 저에게 적합하지 않습니다. 더 이상 최신이 아닌 2016 년 Docker 실행 엔진의 일부 였을까요?
SigmaX

1
@SigmaX Docker가 아니라 Linux에 가깝 습니다. *.sh내부의 모든 파일 /etc/profile.d/은 환경을 채우는 데 사용됩니다
Madacol


7

이 답변에 대한 응답 @DarkSideF ,

그가 제안하는 방법은 다음과 같습니다 Dockerfile.

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

( 에 내보내기 추가/etc/bash.bashrc )

좋지만 환경 변수는 프로세스에서만 사용할 수 있으며 /bin/bash, 예를 들어 Node.js 응용 프로그램과 같은 도커 응용 프로그램을 실행하려고 /etc/bash.bashrc하면 완전히 무시되고 응용 프로그램이 SECRET_KEY_BASE시도 할 때 어떤 단서가 있는지 알 수 없습니다. 에 액세스 process.env.SECRET_KEY_BASE합니다.

그 이유이다 ENV키워드가 모두가 당신이 당신의 용기를 실행하거나 사용할 때마다 때문에 동적 명령을 사용하려고하는 것입니다 exec명령, 부두 노동자가 확인합니다 ENV현재 실행 (유사 과정에서 모든 값을 파이프 -e).

한 가지 해결책은 래퍼를 사용하는 것입니다 ( 이 github 문제 에서 @duglin 에 대한 크레딧 ). 프로젝트 루트에 다음을 포함 하는 래퍼 파일 (예 :)이 있습니다.envwrapper

#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*

그리고 당신의 Dockerfile:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp

2

@DarkSideF의 답변 외에도 Dockerfile 빌드 프로세스 중에 이전 명령의 결과를 재사용하려는 경우 다음 해결 방법을 사용할 수 있습니다.

  1. 명령을 실행하고 결과를 파일에 저장
  2. 명령 대체를 사용하여 해당 파일의 이전 결과를 다른 명령으로 가져옵니다.

예 :

RUN echo "bla" > ./result
RUN echo $(cat ./result)

더 깨끗한 것을 위해 다음과 같은 작은 CLI를 제공하는 요점 을 사용할 수도 있습니다 envstore.py.

RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)

또는 유사한 CLI가있는 python-dotenv 라이브러리를 사용할 수 있습니다 .


2

이것이 당신이 찾고 있던 것인지 확실하지 않지만 ENV vars 또는 ARGS를 .Dockerfile에 삽입하려면이 패턴이 작동합니다.

my_build.sh에서 :

echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')

echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .

.Dockerfile에서 ARG를 얻으려면 스 니펫은 다음과 같습니다.

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

또는 .Dockerfile에서 ENV를 얻으려면 스 니펫이 다음과 같이 보일 수 있습니다.

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

아이디어는 쉘 스크립트를 실행하고 빌드에서 옵션으로 전달 된 인수와 함께 .Dockerfile을 호출하는 것입니다.

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