web-dev-qa-db-fra.com

ARG ou ENV, lequel utiliser dans ce cas?

Cela pourrait peut-être être une question triviale mais lire la documentation pour ARG et ENV ne met pas les choses au clair pour moi.

Je construis un conteneur PHP-FPM et je souhaite donner la possibilité d'activer/désactiver certaines extensions en fonction des besoins des utilisateurs.

Ce serait formidable si cela pouvait être fait dans le fichier Docker en ajoutant des conditions et en transmettant des indicateurs à la commande de construction, mais AFAIK n'est pas pris en charge.

Dans mon cas, mon approche personnelle consiste à exécuter un petit script au démarrage du conteneur, comme 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 "$@"

Voici à quoi ressemble ma 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

Ici est l'ensemble du référentiel si vous devez jeter un regard approfondi afin de 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é pouvant être activée | désactivée, je terminerai avec 20 ENV non nécessaires (car Dockerfile ne supporte pas les fichiers .env) dont le seul but serait de définir cet indicateur pour que le script sache quoi faire alors ...

  • Est-ce que c'est la bonne façon de le faire?
  • Devrais-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

92
ReynierPM

De référence Dockerfile :

  • L'instruction ARG définit une variable que les utilisateurs peuvent transmettre au générateur à l'aide de la commande docker build à l'aide de l'indicateur --build-arg <varname>=<value>.

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

Donc, si vous avez besoin de la personnalisation à la compilation , ARG est votre meilleur choix.
Si vous avez besoin d'une personnalisation au moment de l'exécution (pour exécuter la même image avec des paramètres différents), ENV convient parfaitement.

Si je veux ajouter, disons 20 (un nombre aléatoire) d'extensions ou toute autre fonctionnalité qui peut être activer | désactiver

Étant donné le nombre de combinaisons impliquées, il est préférable d'utiliser ENV pour définir ces fonctionnalités au moment de l'exécution.

Mais vous pouvez combiner les deux en:

  • construction d'une image avec un ARG spécifique
  • en utilisant ce ARG en tant que ENV

C'est-à-dire avec un fichier Docker comprenant:

ARG var
ENV var=${var}

Vous pouvez ensuite créer une image avec une valeur var spécifique 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).

168
VonC