ARG 或 ENV,在这种情况下使用哪个? [英] ARG or ENV, which one to use in this case?
问题描述
这可能是一个微不足道的问题,但阅读 ARG 和ENV 并没有让我清楚.
我正在构建一个 PHP-FPM 容器,我希望能够根据用户需要启用/禁用某些扩展.
如果这可以在 Dockerfile 中通过在构建命令上添加条件和传递标志来完成,那就太好了,但不支持 AFAIK.
就我而言,我个人的方法是在容器启动时运行一个小脚本,如下所示:
#!/bin/sh设置 -eRESTART=假"# 这个脚本会被放置在/config/init/并在容器启动时运行.if [ "$INSTALL_XDEBUG";==真"];然后printf "\n正在安装 Xdebug ...\n";yum install -y php71-php-pecl-xdebugRESTART=真"菲...如果 [ "$RESTART";==真"];然后printf "\n重新启动 php-fpm ...\n";supervisorctl 重启 php-fpm菲执行$@"
这是我的 Dockerfile
的样子:
FROM reynierpm/centos7-supervisor环境术语=xterm \PATH="/root/.composer/vendor/bin:${PATH}";\INSTALL_COMPOSER="假"\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=假"\SYMFONY_PROJECT=假"\INSTALL_XDEBUG=假"\INSTALL_MONGO=假"\INSTALL_REDIS =假"\INSTALL_HTTP_REQUEST=假"\INSTALL_UPLOAD_PROGRESS=假";\INSTALL_XATTR=假"运行 yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \https://rpms.remirepo.net/enterprise/remi-release-7.rpm运行 yum install -y \yum-utils \混帐\压缩 \解压\纳米\获取\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-梨\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*运行 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复制容器文件/运行 chmod +x/config/bootstrap.sh工作目录/数据/www曝光 9001
目前这是有效的,但是...如果我想添加 20 个(随机数)扩展或任何其他可以启用的功能|禁用,那么我将以 20 个非必要的 ENV结尾代码>(因为 Dockerfile 不支持 .env 文件)定义,其唯一目的是设置这个标志,让脚本知道接下来要做什么......
- 这是正确的做法吗?
- 我应该为此使用
ENV
吗?
如果您有不同的方法来实现这一点,我愿意接受想法,请告诉我
一个>:
<块引用>ARG
指令定义了一个变量,用户可以在构建时使用--build-arg
标志.= 使用 docker build 命令将变量传递给构建器<值> ENV
指令将环境变量
设置为值
.
使用ENV
设置的环境变量将在从生成的映像运行容器时持续存在.
因此,如果您需要构建时自定义,ARG
是您的最佳选择.
如果您需要运行时自定义(以不同的设置运行相同的图像),ENV
非常适合.
如果我想添加 20 个(随机数)扩展或任何其他可以启用的功能|禁用
考虑到所涉及的组合数量,最好在这里使用 ENV
在运行时设置这些功能.
但您可以通过以下方式结合:
- 使用特定的
ARG
构建图像 - 使用
ARG
作为ENV
也就是说,一个 Dockerfile 包括:
ARG 变量环境变量=${var}
然后,您可以在构建时构建具有特定 var
值的映像 (docker build --build-arg var=xxx
),或运行容器具有特定的运行时值 (docker run -e var=yyy
)
This could be maybe a trivial question but reading docs for ARG and ENV doesn't put things clear to me.
I am building a PHP-FPM container and I want to give the ability for enable/disable some extensions on user needs.
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 "$@"
This is how my Dockerfile
looks like:
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
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 ...
- Is this the right way to do it?
- Should I use
ENV
for this purpose?
I am open to ideas if you have a different approach for achieve this please let me know about it
From Dockerfile reference:
The
ARG
instruction defines a variable that users can pass at build-time to the builder with the docker build command using the--build-arg <varname>=<value>
flag.The
ENV
instruction sets the environment variable<key>
to the value<value>
.
The environment variables set usingENV
will persist when a container is run from the resulting image.
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.
If I want to add let's say 20 (a random number) of extensions or any other feature that can be enable|disable
Given the number of combinations involved, using ENV
to set those features at runtime is best here.
But you can combine both by:
- building an image with a specific
ARG
- using that
ARG
as anENV
That is, with a Dockerfile including:
ARG var
ENV var=${var}
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,在这种情况下使用哪个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!