Это может быть тривиальный вопрос, но чтение документации по ARG и ENV не проясняет мне ситуацию.
Я создаю контейнер PHP-FPM и хочу дать возможность включать / отключать некоторые расширения по потребностям пользователя.
Было бы здорово, если бы это можно было сделать в Dockerfile, добавив условные обозначения и передав флаги в команду сборки, но AFAIK не поддерживается.
В моем случае и мой личный подход - запускать небольшой скрипт при запуске контейнера, примерно так:
#!/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 "$@"
Вот как 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
Вот весь репозиторий, если вам нужно внимательно изучить, чтобы понять, как я делаю что-то
В настоящее время это работает, но ... Если я хочу добавить, скажем, 20 (случайное число) расширений или любую другую функцию, которую можно включить | отключить, тогда я ENV
закончу с 20 ненужными (потому что Dockerfile не поддерживает .env files), единственной целью которого будет установка этого флага, чтобы сценарий знал, что делать дальше ...
- Это правильный способ сделать это?
- Стоит ли использовать
ENV
для этой цели?
Я открыт для идей, если у вас есть другой подход для достижения этой цели, сообщите мне об этом.
источник
ARG
чтобы установить для них разные значения с каждой используемой сборкой--build-arg
, и вы все равно можете использовать значения по умолчанию в Dockerfile. Если вы используетеENV
, вам нужно будет отредактировать сам Dockerfile для каждой сборки, чтобы установить разные значенияОтветы:
Из ссылки Dockerfile :
Так что, если вам нужна настройка во время сборки ,
ARG
это ваш лучший выбор.Если вам нужна настройка во время выполнения (для запуска одного и того же образа с разными настройками),
ENV
это хорошо подходит.Учитывая количество задействованных комбинаций, используя
ENV
лучше всего для установки этих функций во время выполнения.Но вы можете комбинировать и то, и другое :
ARG
ARG
какENV
То есть с Dockerfile, включающим:
Затем вы можете либо создать образ с определенным
var
значением в build-time (docker build --build-arg var=xxx
), либо запустить контейнер с определенным значением времени выполнения (docker run -e var=yyy
)источник
ARG
можно получить доступ из сценария, который я запускаю при запуске контейнера? Если да, то как? Не могли бы вы улучшить свой ответ, добавив небольшой пример того, как к ним можно получить доступ из сценария bash?ARG
,ENV var=${var}
: см stackoverflow.com/a/33936014/6309 . Используйте оба.var
получу с переменной ENV в контейнере при его запуске, я прав? Иначе я вообще не слежу за тобой. Помните: сценарий копируется из локальной папки в контейнер и используется при инициализации контейнера, поэтому я использую ENV вместо ARG, потому что я не знаю, работает ли ARG при запуске контейнера и может быть доступен изнутри. сценарий bash.Поэтому, если вы хотите установить значение переменной среды на что-то другое для каждой сборки, мы можем передавать эти значения во время сборки, и нам не нужно каждый раз изменять наш файл докеров.
В
ENV
то время как однажды установленный не может быть перезаписан через значения командной строки. Итак, если мы хотим, чтобы наша переменная среды имела разные значения для разных сборок, мы могли бы использоватьARG
и устанавливать значения по умолчанию в нашем файле докеров. И когда мы хотим перезаписать эти значения, мы можем сделать это, используя--build-args
при каждой сборке, не изменяя наш файл докеров.Для получения дополнительной информации вы можете обратиться к этому .
источник