ARG或ENV,在这种情况下使用哪一个?

时间:2017-01-29 00:24:58

标签: docker arguments environment-variables dockerfile

这可能是一个微不足道的问题,但阅读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

Here是整个存储库,如果您需要深入了解以了解我的工作方式

目前这是有效的,但是...如果我想添加让我们说20(随机数)的扩展名或任何其他可以启用|禁用的功能,那么我将以20个非必要{{}结尾1}}(因为Dockerfile不支持.env文件)定义,其唯一目的是设置此标志,让脚本知道该怎么做...

  • 这是正确的方法吗?
  • 我应该ENV用于此目的吗?

如果您有不同的方法来实现这一点,我愿意接受我的想法

2 个答案:

答案 0 :(得分:152)

来自Dockerfile reference

  
      
  • ARG指令定义了一个变量,用户可以使用--build-arg <varname>=<value>标志使用docker build命令在构建时将其传递给构建器。

  •   
  • ENV指令将环境变量<key>设置为值<value>
      从结果图像运行容器时,使用ENV设置的环境变量将保持不变。

  •   

因此,如果您需要构建时间自定义,ARG是您的最佳选择。
如果您需要运行时自定义(使用不同的设置运行相同的图像),ENV非常适合。

  

如果我想添加让我们说20(随机数)的扩展名或任何其他可以启用|禁用的功能

考虑到所涉及的组合数量,最好使用ENV在运行时设置这些功能。

但你可以combine both通过:

  • 使用特定的ARG
  • 构建图像
  • ARG用作ENV

即使用包含以下内容的Dockerfile:

ARG var
ENV var=${var}

然后,您可以在构建时(var)构建具有特定docker build --build-arg var=xxx值的图像,或者运行具有特定运行时值(docker run -e var=yyy)的容器

答案 1 :(得分:0)

因此,如果要将每个构建的环境变量的值设置为不同的值,那么我们可以在构建期间传递这些值,而不必每次都更改docker文件。

ENV设置后,不能通过命令行值覆盖。因此,如果我们想让我们的环境变量对不同的构建具有不同的值,则可以使用ARG并在docker文件中设置默认值。而且,当我们想覆盖这些值时,我们可以在每次构建时都使用--build-args,而无需更改我们的docker文件。

有关更多详细信息,请参阅this