本文介绍了ARG或ENV,在这种情况下使用哪个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个琐碎的问题,但要阅读 ARG ENV 不能使我明白.

This could be maybe a trivial question but reading docs for ARG and ENV doesn't put things clear to me.

我正在构建一个PHP-FPM容器,我希望能够根据用户需要启用/禁用某些扩展.

I am building a PHP-FPM container and I want to give the ability for enable/disable some extensions on user needs.

如果可以在Dockerfile中通过添加条件并在build命令上传递标志来做到这一点,那将是很棒的选择,但不支持AFAIK.

Would be great if this could be done in the Dockerfile by adding conditionals and passing flags on the build command perhaps but AFAIK is not supported.

就我而言,我的个人方法是在容器启动时运行一个小的脚本,如下所示:

In my case and my personal approach is to run a small script when container starts, something like the following:

#!/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 is the whole repository if you need to take a deep look in order to understand how I am doing things

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

Currently this is working but ... If I want to add let's say 20 (a random number) of extensions or any other feature that can be enable|disable then I will end with 20 non necessary ENV (because Dockerfile doesn't support .env files) definition whose only purpose would be set this flag for let the script knows what to do then ...

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

如果您有其他实现此目标的方法,我欢迎您提出想法

I am open to ideas if you have a different approach for achieve this please let me know about it

推荐答案

来自 Dockerfile参考:

ENV指令将环境变量<key>设置为值<value>.
从结果映像运行容器时,使用ENV设置的环境变量将保留.

The ENV instruction sets the environment variable <key> to the value <value>.
The environment variables set using ENV will persist when a container is run from the resulting image.

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

So if you need build-time customization, ARG is your best choice.
If you need run-time customization (to run the same image with different settings), ENV is well-suited.

鉴于涉及的组合数量,最好在运行时使用ENV设置这些功能.

Given the number of combinations involved, using ENV to set those features at runtime is best here.

但是您可以将两者结合,方法是:

  • 使用特定的ARG
  • 构建图像
  • 使用该ARG作为ENV
  • building an image with a specific ARG
  • using that ARG as an ENV

也就是说,使用包含以下内容的Dockerfile:

That is, with a Dockerfile including:

ARG var
ENV var=${var}

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

You can then either build an image with a specific var value at build-time (docker build --build-arg var=xxx), or run a container with a specific runtime value (docker run -e var=yyy)

这篇关于ARG或ENV,在这种情况下使用哪个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 03:12