192 votes

ARG ou ENV, lequel utiliser dans ce cas ?

Il s'agit peut-être d'une question triviale, mais en lisant les documents relatifs aux ARG y ENV ne rend pas les choses claires pour moi.

Je construis un conteneur PHP-FPM et je veux donner la possibilité d'activer/désactiver certaines extensions selon les besoins de l'utilisateur.

Ce serait génial si cela pouvait être fait dans le Dockerfile en ajoutant des conditions et en passant des drapeaux sur la commande de construction peut-être mais AFAIK n'est pas supporté.

Dans mon cas et mon approche personnelle est d'exécuter un petit script lorsque le conteneur démarre, quelque chose comme ce qui suit :

#!/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 "$@"

C'est ainsi que mon Dockerfile ressemble :

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

Ici Voici le référentiel complet si vous avez besoin de regarder en profondeur pour comprendre comment je fais les choses.

Actuellement, cela fonctionne mais ... Si je veux ajouter disons 20 (un nombre aléatoire) d'extensions ou toute autre fonctionnalité qui peut être activée/désactivée, je finirai avec 20 non nécessaires. ENV (parce que Dockerfile ne supporte pas les fichiers .env) définition dont le seul but serait de mettre ce drapeau pour que le script sache quoi faire ensuite ...

  • Est-ce la bonne façon de procéder ?
  • Dois-je utiliser ENV à cette fin ?

Je suis ouvert aux idées, si vous avez une approche différente pour y parvenir, faites-le moi savoir.

337voto

VonC Points 414372

De Référence au Dockerfile :

  • El ARG définit une variable que les utilisateurs peuvent transmettre au moment de la construction au constructeur avec la commande docker build en utilisant l'instruction --build-arg <varname>=<value> drapeau.

  • El ENV L'instruction définit la variable d'environnement <key> à la valeur <value> .
    Les variables d'environnement définies à l'aide de ENV persistera lorsqu'un conteneur sera exécuté à partir de l'image résultante.

Donc si vous avez besoin temps de construction personnalisation, ARG est votre meilleur choix.
Si vous avez besoin de personnaliser l'exécution (pour exécuter la même image avec des paramètres différents), ENV est bien adapté.

Si je veux ajouter, disons, 20 (un nombre aléatoire) extensions ou toute autre fonctionnalité qui peut être activée/désactivée

Compte tenu du nombre de combinaisons concernées, l'utilisation de ENV pour définir ces caractéristiques au moment de l'exécution est le mieux ici.

Mais vous pouvez combiner les deux par :

  • construire une image avec une ARG
  • en utilisant ce ARG comme un ENV

C'est-à-dire, avec un Dockerfile comprenant :

ARG var
ENV var=${var}

Vous pouvez alors soit construire une image avec une image spécifique. var au moment de la construction ( docker build --build-arg var=xxx ), ou exécuter un conteneur avec une valeur d'exécution spécifique ( docker run -e var=yyy )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X