web-dev-qa-db-ja.com

ARGとENVのどちらを使用しますか。

これは些細な問題かもしれませんが、 ARG および ENV のドキュメントを読んでも、物事が明確になるわけではありません。 。

私はPHP-FPMコンテナを構築しています、そして私はユーザーのニーズに応じていくつかの拡張機能を有効/無効にする機能を与えたいと思います。

これがDockerfileで、条件を追加してbuildコマンドにフラグを渡すことで実行できれば素晴らしいのですが、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個(乱数)の拡張機能や他の有効または無効にできる機能を追加したいのであれば、20個の不要なENVで終わります。唯一の目的がスクリプトに何をすべきかを知らせるためにこのフラグを設定することになるenv files)定義...

  • これは正しいやり方ですか?
  • この目的のためにENVを使うべきですか?

あなたがこれを達成するための別のアプローチがある場合は私はアイデアを開いていますそれについて私に知らせてください

82
ReynierPM

Dockerfile参照から

  • ARG命令は、ユーザーが--build-arg <varname>=<value>フラグを使用してdocker buildコマンドでビルド時にビルダーに渡すことができる変数を定義します。

  • ENV命令は、環境変数<key>を値<value>に設定します。
    ENVを使用して設定された環境変数は、結果のイメージからコンテナが実行されても存続します。

したがって、ビルド時のカスタマイズが必要な場合は、ARGが最善の選択です。
(異なる設定で同じイメージを実行するために)実行時のカスタマイズが必要な場合は、ENVが適しています。

私が追加したいのであれば、20(乱数)の拡張機能、または有効にできるその他の機能を言ってみましょう。

含まれる組み合わせの数を考えると、実行時にこれらの機能を設定するためにENVを使用するのがここでは最良です。

しかし、 を組み合わせて

  • 特定のARGを使って画像を作成する
  • そのARGENVとして使う

つまり、Dockerfileでは以下のようになります。

ARG var
ENV var=${var}

その後、ビルド時に特定のvar値を使用してイメージをビルドするか(docker build --build-arg var=xxx)、または特定のランタイム値を使用してコンテナを実行することができます(docker run -e var=yyy)。

154
VonC