Esta podría ser una pregunta trivial, pero leer documentos para ARG y ENV no me aclara las cosas.
Estoy construyendo un contenedor PHP-FPM y quiero brindar la posibilidad de habilitar / deshabilitar algunas extensiones según las necesidades del usuario.
Sería genial si esto se pudiera hacer en el Dockerfile agregando condicionales y pasando banderas en el comando de compilación, pero AFAIK no es compatible.
En mi caso y mi enfoque personal es ejecutar un pequeño script cuando se inicia el contenedor, algo como lo siguiente:
#!/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 "$@"
Así es como se Dockerfile
ve mi :
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
Aquí está el repositorio completo si necesita echar un vistazo en profundidad para comprender cómo estoy haciendo las cosas
Actualmente esto funciona, pero ... Si quiero agregar, digamos 20 (un número aleatorio) de extensiones o cualquier otra característica que se pueda habilitar | deshabilitar, terminaré con 20 no necesarias ENV
(porque Dockerfile no admite .env files) definición cuyo único propósito sería establecer esta bandera para que el script sepa qué hacer luego ...
- ¿Esta es la manera correcta de hacerlo?
- ¿Debo usar
ENV
para este propósito?
Estoy abierto a ideas si tiene un enfoque diferente para lograr esto, hágamelo saber
fuente
ARG
para configurarlas con valores diferentes con cada compilación usando--build-arg
, y aún puede usar valores predeterminados en el Dockerfile. Si lo usaENV
, necesitaría editar el Dockerfile para cada compilación para establecer diferentes valoresRespuestas:
De la referencia de Dockerfile :
Entonces, si necesita personalización en el tiempo de construcción ,
ARG
es su mejor opción.Si necesita personalización en tiempo de ejecución (para ejecutar la misma imagen con diferentes configuraciones),
ENV
es adecuado.Dada la cantidad de combinaciones involucradas, usar
ENV
para configurar esas características en tiempo de ejecución es mejor aquí.Pero puedes combinar ambos mediante:
ARG
ARG
como unENV
Es decir, con un Dockerfile que incluye:
A continuación, puede crear una imagen con un
var
valor específico en el tiempo de compilación (docker build --build-arg var=xxx
) o ejecutar un contenedor con un valor de tiempo de ejecución específico (docker run -e var=yyy
)fuente
ARG
se puede acceder a ellos desde el script que estoy ejecutando al iniciar el contenedor? ¿Si es así, cómo? ¿Podría mejorar su respuesta agregando un pequeño ejemplo sobre cómo se puede acceder a ellos desde un script bash?ARG
, unENV var=${var}
: consulte stackoverflow.com/a/33936014/6309 . Utilice ambos.var
variable ENV en el contenedor cuando comience, ¿tengo razón? De lo contrario, no te seguiré en absoluto. Recuerde esto: el script se copia de una carpeta local al contenedor y se usa después de la inicialización del contenedor, por eso estoy usando ENV en lugar de ARG porque no sé si cuando el contenedor se inicia, el ARG sigue vivo y se puede acceder desde adentro un guión bash.Entonces, si desea establecer el valor de una variable de entorno en algo diferente para cada compilación, entonces podemos pasar estos valores durante el tiempo de compilación y no es necesario que cambiemos nuestro archivo docker cada vez.
Mientras que
ENV
, una vez configurado, no se puede sobrescribir a través de los valores de la línea de comando. Entonces, si queremos que nuestra variable de entorno tenga diferentes valores para diferentes compilaciones, entonces podríamos usarARG
y establecer valores predeterminados en nuestro archivo docker. Y cuando queremos sobrescribir estos valores, podemos hacerlo usando--build-args
en cada compilación sin cambiar nuestro archivo docker.Para obtener más detalles, puede consultar esto .
fuente