Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

docker - ARG or ENV, which one to use in this case?

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 "
Installing Xdebug ...
"
    yum install -y  php71-php-pecl-xdebug
    RESTART="true"
fi
...   
if  [ "$RESTART" == "true" ]; then
    printf "
Restarting php-fpm ...
"
    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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 using ENV 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 an ENV

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...