ARG 또는 ENV,이 경우 어느 것을 사용해야합니까?


122

이것은 사소한 질문이 될 수 있지만 ARGENV에 대한 문서를 읽는 것이 분명하지 않습니다.

PHP-FPM 컨테이너를 구축 중이며 사용자 요구에 따라 일부 확장을 활성화 / 비활성화하는 기능을 제공하고 싶습니다.

조건을 추가하고 빌드 명령에 플래그를 전달하여 Dockerfile에서이 작업을 수행 할 수 있다면 좋겠지 만 AFAIK는 지원되지 않습니다.

제 경우와 개인적인 접근 방식은 컨테이너가 시작될 때 다음과 같은 작은 스크립트를 실행하는 것입니다.

#!/bin/sh   
set -e

RESTART="false"

# This script will be placed in /config/init/ and run when container starts.
if  [ "$INSTALL_XDEBUG" == "true" ]; then
    printf "\nInstalling Xdebug ...\n"
    yum install -y  php71-php-pecl-xdebug
    RESTART="true"
fi
...   
if  [ "$RESTART" == "true" ]; then
    printf "\nRestarting php-fpm ...\n"
    supervisorctl restart php-fpm
fi

exec "$@"

이것은 내 Dockerfile모습입니다.

FROM reynierpm/centos7-supervisor
ENV TERM=xterm \
    PATH="/root/.composer/vendor/bin:${PATH}" \
    INSTALL_COMPOSER="false" \
    COMPOSER_ALLOW_SUPERUSER=1 \
    COMPOSER_ALLOW_XDEBUG=1 \
    COMPOSER_DISABLE_XDEBUG_WARN=1 \
    COMPOSER_HOME="/root/.composer" \
    COMPOSER_CACHE_DIR="/root/.composer/cache" \
    SYMFONY_INSTALLER="false" \
    SYMFONY_PROJECT="false" \
    INSTALL_XDEBUG="false" \
    INSTALL_MONGO="false" \
    INSTALL_REDIS="false" \
    INSTALL_HTTP_REQUEST="false" \
    INSTALL_UPLOAD_PROGRESS="false" \
    INSTALL_XATTR="false"

RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
                   https://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum install -y  \
        yum-utils \
        git \
        zip \
        unzip \
        nano \
        wget \
        php71-php-fpm \
        php71-php-cli \
        php71-php-common \
        php71-php-gd \
        php71-php-intl \
        php71-php-json \
        php71-php-mbstring \
        php71-php-mcrypt \
        php71-php-mysqlnd \
        php71-php-pdo \
        php71-php-pear \
        php71-php-xml \
        php71-pecl-apcu \
        php71-php-pecl-apfd \
        php71-php-pecl-memcache \
        php71-php-pecl-memcached \
        php71-php-pecl-zip && \
        yum clean all && rm -rf /tmp/yum*

RUN ln -sfF /opt/remi/php71/enable /etc/profile.d/php71-paths.sh && \
    ln -sfF /opt/remi/php71/root/usr/bin/{pear,pecl,phar,php,php-cgi,phpize} /usr/local/bin/. && \
    mv -f /etc/opt/remi/php71/php.ini /etc/php.ini && \
    ln -s /etc/php.ini /etc/opt/remi/php71/php.ini && \
    rm -rf /etc/php.d && \
    mv /etc/opt/remi/php71/php.d /etc/. && \
    ln -s /etc/php.d /etc/opt/remi/php71/php.d

COPY container-files /
RUN chmod +x /config/bootstrap.sh
WORKDIR /data/www
EXPOSE 9001

여기에 내가이 일을 얼마나 이해하기 위해 깊은 살펴해야 할 경우 전체 저장소입니다

현재 이것은 작동하고 있지만 ... 20 (임의의 숫자)의 확장 기능이나 활성화 / 비활성화 할 수있는 다른 기능을 추가하려면 필요 ENV하지 않은 20 개로 끝낼 것입니다 (Dockerfile이 .env를 지원하지 않기 때문). 파일) 정의는 스크립트가 수행 할 작업을 알 수 있도록이 플래그를 설정하는 유일한 목적입니다.

  • 이것이 올바른 방법입니까?
  • ENV이 목적으로 사용해야 합니까?

나는 당신이 이것을 달성하기 위해 다른 접근 방식을 가지고 있다면 아이디어에 열려 있습니다.


이러한 확장 / 기능이 빌드마다 다를 경우 ARG를 사용 하여 각 빌드에서 다른 값으로 설정해야 --build-arg하며 Dockerfile에서 기본값을 계속 사용할 수 있습니다. 를 사용하는 경우 ENV모든 빌드에 대해 Dockerfile 자체를 편집하여 다른 값을 설정해야합니다
AA

답변:


216

에서 Dockerfile 참조 :

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

  • ENV지시는 환경 변수 설정 <key>값을 <value>.
    을 사용하여 설정된 환경 변수 ENV는 결과 이미지에서 컨테이너가 실행될 때 유지됩니다.

따라서 빌드 타임 사용자 지정 이 필요한 경우 ARG최선의 선택입니다.
다른 설정으로 동일한 이미지를 실행하기 위해 런타임 사용자 지정이 필요한 경우에 ENV적합합니다.

추가하려면 20 (임의의 숫자) 확장 또는 활성화 | 비활성화 할 수있는 다른 기능을 가정 해 보겠습니다.

관련된 조합의 수를 고려할 때 ENV런타임에 이러한 기능을 설정하는 데 사용 하는 것이 가장 좋습니다.

그러나 다음 과 같이 두 가지결합 할 수 있습니다 .

  • 특정 이미지 구축 ARG
  • 그것을 ARG사용하여ENV

즉, 다음을 포함하는 Dockerfile을 사용합니다.

ARG var
ENV var=${var}

그런 다음 빌드시 특정 var값으로 이미지 를 빌드 docker build --build-arg var=xxx하거나 ( ) 특정 런타임 값으로 컨테이너를 실행할 수 있습니다 ( docker run -e var=yyy).


1
훌륭하지만 ARG컨테이너 시작시 실행중인 스크립트에서 액세스 할 수 있습니까? 그렇다면 어떻게? bash 스크립트에서 액세스 할 수있는 방법에 대한 간단한 예제를 추가하여 답변을 개선 할 수 있습니까?
ReynierPM

@ReynierPM 당신은에, 당신의 Dockerfile (빌드 시간)에 선언 할 수 있습니다 또한ARG, ENV var=${var}: 참조 stackoverflow.com/a/33936014/6309를 . 둘 다 사용하십시오.
VonC

내가 당신의 접근 방식을 사용 var하면 시작될 때 컨테이너 에서 ENV 변수로 끝나는 것이 무엇이든간에 맞습니까? 그렇지 않으면 나는 당신을 전혀 따르지 않습니다. 이것을 기억하십시오 : 스크립트는 로컬 폴더에서 컨테이너로 복사되고 컨테이너 초기화시 사용됩니다. 컨테이너가 ARG를 시작할 때 아직 살아 있고 내부에서 액세스 할 수 있는지 모르기 때문에 ARG 대신 ENV를 사용하는 이유입니다. bash 스크립트.
ReynierPM

당신이 그것 봐, 내가 현재 무엇을하고 무엇을 알 수 있도록 내 Dockerfile을 추가 한
ReynierPM

1
@HardeepSingh 둘 다 : ENV ( stackoverflow.com/a/33836848/6309 ) 및 ARG ( stackoverflow.com/a/41593407/6309 )
VonC

0

따라서 환경 변수의 값을 빌드마다 다른 값으로 설정하려면 빌드 시간 동안이 값을 전달할 수 있으며 매번 도커 파일을 변경할 필요가 없습니다.

동안 ENV집합 명령 행 값을 덮어 쓸 수 없습니다되면. 따라서 환경 변수가 빌드마다 다른 값을 갖도록하려면 ARGdocker 파일에서 기본값을 사용 하고 설정할 수 있습니다 . 그리고 이러한 값을 덮어 쓰고 싶을 때 --build-args도커 파일을 변경하지 않고 모든 빌드에서 사용하면 됩니다.

자세한 내용은 여기를 참조 하십시오 .

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