2017-01-29 17 views
42

Возможно, это может быть тривиальный вопрос, но чтение документов для ARG и ENV не дает мне понять.ARG или ENV, какой из них использовать в этом случае?

Я создаю контейнер PHP-FPM, и я хочу дать возможность включать/отключать некоторые расширения по потребностям пользователей.

Было бы здорово, если бы это можно было сделать в файле Docker, добавив условные обозначения и пропущенные флаги в команде сборки, возможно, 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 "[email protected]" 

Это как мой 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 

Here является весь репозиторий, если вам нужно глубоко изучить, чтобы понять, как я делаю вещи

В настоящее время это работает, но. Если я хочу добавить, скажем, 20 (случайное число) расширений или любую другую функцию, которая может быть включена | отключить, тогда я закончу с 20 ненужными ENV (потому что Dockerfile не поддерживает файлы .env) определение, единственное Цель будет установить этот флаг, чтобы сценарий знал, что делать тогда ...

  • Это правильный способ сделать это?
  • Должен ли я использовать ENV для этой цели?

Я открыт для идей, если у вас есть другой подход для достижения этой цели, пожалуйста, дайте мне знать об этом

+0

Если эти расширения/функции будут отличаться от одной сборки к другой, то вы должны использовать 'ARG', чтобы устанавливать их с разными значениями при каждой сборке с использованием' --build-arg', и вы все равно можете использовать значения по умолчанию в файле Docker. Если вы используете 'ENV', вам нужно будет отредактировать сам файл Docker для каждой сборки, чтобы установить разные значения. –

ответ

85

От Dockerfile reference:

  • ARG инструкция определяет переменную, что пользователи может пройти в build-time для строителя с помощью команды сборки докеров, используя флаг --build-arg <varname>=<value>.

  • Инструкция ENV устанавливает переменную окружения <key> на значение <value>.
    Переменные окружения, заданные с использованием ENV, сохраняются, когда контейнер запускается из полученного изображения.

Так что, если вам нужно сборки времени настройки, ARG это ваш лучший выбор.
Если вам нужна настройка времени выполнения (для запуска того же изображения с разными настройками), ENV подходит.

Если я хочу добавить, скажем, 20 (случайное число) расширений или любой другой функции, которая может быть включить | отключить

Учитывая количество комбинаций, участвующих, используя ENV установить эти функции во время выполнения лучше всего здесь.

Но вы можете combine both по:

  • строит изображение с определенной ARG
  • , используя которые ARG как ENV

То есть, с Dockerfile в том числе:

ARG var 
ENV var=${var} 

Затем вы можете построить изображение со значением var во время сборки (docker build --build-arg var=xxx) или запустить контейнер с определенным значением времени выполнения (docker run -e var=yyy)

+0

Отлично, но эти' ARG' могут быть доступны из сценария, который я запускаю при запуске контейнера? Если да, то как? Не могли бы вы улучшить свой ответ, добавив небольшой пример того, как к ним можно получить доступ из сценария bash? – ReynierPM

+0

@ReynierPM вы можете, объявив в своем файле Dockerfile (время сборки), в * добавлении * 'ARG',' ENV var = $ {var} ': см. Http://stackoverflow.com/a/33936014/6309 , Используйте оба варианта. – VonC

+0

Если я использую ваш подход, то независимо от того, что в конечном итоге я вернусь к переменной var var в контейнере, я прав? В противном случае я вообще не буду следовать за тобой. Помните следующее: сценарий копируется из локальной папки в контейнер и используется при инициализации контейнера, поэтому я использую ENV вместо ARG, потому что не знаю, будет ли когда контейнер запускать ARG еще живым и к нему можно получить доступ изнутри скрипт bash. – ReynierPM

 Смежные вопросы

  • Нет связанных вопросов^_^