Esta pode ser uma questão trivial, mas ler documentos para ARG e ENV não deixa as coisas claras para mim.
Estou construindo um contêiner PHP-FPM e desejo habilitar / desabilitar algumas extensões de acordo com as necessidades do usuário.
Seria ótimo se isso pudesse ser feito no Dockerfile adicionando condicionais e passando sinalizadores no comando de construção, talvez, mas AFAIK não é suportado.
No meu caso e minha abordagem pessoal é executar um pequeno script quando o contêiner é iniciado, algo como o seguinte:
#!/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 "$@"
É assim que meu se Dockerfile
parece:
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
Aqui está o repositório completo, se você precisar dar uma olhada em profundidade para entender como estou fazendo as coisas
Atualmente, isso está funcionando, mas ... Se eu quiser adicionar, digamos, 20 (um número aleatório) de extensões ou qualquer outro recurso que possa ser habilitado | desabilitado, terminarei com 20 não necessários ENV
(porque o Dockerfile não oferece suporte a .env arquivos) definição cujo único propósito seria definir este sinalizador para permitir que o script saiba o que fazer então ...
- Esse é o jeito certo de fazer?
- Devo usar
ENV
para esse fim?
Estou aberto a ideias, se você tiver uma abordagem diferente para conseguir isso, por favor me informe sobre isso
fonte
ARG
para defini-los com valores diferentes com cada compilação usando--build-arg
, e você ainda pode usar os valores padrão no Dockerfile. Se você usarENV
, precisará editar o próprio Dockerfile para cada construção para definir valores diferentesRespostas:
Da referência do Dockerfile :
Portanto, se você precisar de personalização em tempo de construção ,
ARG
é sua melhor escolha.Se você precisa de personalização em tempo de execução (para executar a mesma imagem com configurações diferentes),
ENV
é adequado.Dado o número de combinações envolvidas, usar
ENV
para definir esses recursos em tempo de execução é melhor aqui.Mas você pode combinar ambos :
ARG
ARG
como umENV
Ou seja, com um Dockerfile incluindo:
Você pode então construir uma imagem com um
var
valor específico em tempo de construção (docker build --build-arg var=xxx
) ou executar um contêiner com um valor de tempo de execução específico (docker run -e var=yyy
)fonte
ARG
podem ser acessados a partir do script que estou executando na inicialização do contêiner? Se sim, como? Você poderia melhorar sua resposta adicionando um pequeno exemplo sobre como eles podem ser acessados a partir de um script bash?ARG
umENV var=${var}
: consulte stackoverflow.com/a/33936014/6309 . Use ambos.var
variável ENV no contêiner quando ele iniciar, estou certo? Caso contrário, não estou te seguindo de forma alguma. Lembre-se disso: o script é copiado de uma pasta local para o contêiner e é usado na inicialização do contêiner, é por isso que estou usando ENV em vez de ARG porque não sei se quando o contêiner inicia o ARG ainda está vivo e pode ser acessado de dentro um script bash.Portanto, se quisermos definir o valor de uma variável de ambiente para algo diferente para cada construção, podemos passar esses valores durante o tempo de construção e não precisamos alterar nosso arquivo docker todas as vezes.
Enquanto
ENV
, uma vez definido, não pode ser substituído por meio de valores de linha de comando. Portanto, se quisermos que nossa variável de ambiente tenha valores diferentes para diferentes compilações, podemos usarARG
e definir os valores padrão em nosso arquivo docker. E quando quisermos sobrescrever esses valores, podemos fazer isso usando--build-args
em cada compilação, sem alterar nosso arquivo docker.Para mais detalhes, você pode consultar isto .
fonte