ARGまたはENV、この場合どちらを使用しますか?


121

これはささいな質問かもしれませんが、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(乱数)の拡張機能またはその他の有効/無効にできる機能を追加したい場合は、20で終了しますENV(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
  • それARGENV

つまり、以下を含むDockerfileを使用します。

ARG var
ENV var=${var}

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


1
すばらしいですが、これらARGはコンテナの起動時に実行しているスクリプトからアクセスできますか?もしそうなら?bashスクリプトからこれらにアクセスする方法についての小さな例を追加して、回答を改善できますか?
ReynierPM 2017年

で、あなたのDockerfile(ビルド時)に宣言し@ReynierPMすることができます、追加ARGENV var=${var}以下を参照してくださいstackoverflow.com/a/33936014/6309を。両方を使う。
VonC、2017年

私があなたのアプローチを使用するならばvar、それがそれが始まるとき、私がコンテナのENV変数で何に終わっても、私は正しいですか?そうでなければ、私はあなたについて全然フォローしていません。これを覚えておいてください:スクリプトはローカルフォルダーからコンテナーにコピーされ、コンテナーの初期化時に使用されます。これが、ARGの代わりにENVを使用している理由です。コンテナーがARGをいつ開始するかがわからず、内部からアクセスできるかどうかがわからないためです。 bashスクリプト。
ReynierPM、2017年

Dockerfileを追加しました。これを見て、私が現在何をしているのかを確認できます
ReynierPM

1
@HardeepSingh Both:ENV(stackoverflow.com/a/33836848/6309)およびARG(stackoverflow.com/a/41593407/6309
VonC

0

したがって、環境変数の値をビルドごとに異なる値に設定したい場合は、ビルド時にこれらの値を渡すことができ、毎回dockerファイルを変更する必要はありません。

一方ENV、一度設定された値は、コマンドライン値で上書きできません。したがって、環境変数にビルドごとに異なる値をARG設定したい場合は、Dockerファイルでデフォルト値を使用および設定できます。そして、これらの値を上書きしたい場合は--build-args、Dockerファイルを変更せずに、すべてのビルドで使用できます。

詳細については、こちらを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.