2017-01-29 6 views
42

Może to być może trywialne pytanie, ale czytanie dokumentów dla ARG i ENV nie daje mi jasności.ARG lub ENV, którego użyć w tym przypadku?

Buduję kontener PHP-FPM i chcę umożliwić włączanie/wyłączanie niektórych rozszerzeń na potrzeby użytkowników.

Byłoby wspaniale, gdyby można było to zrobić w pliku Dockerfix poprzez dodanie warunków i przekazywanie flag na komendzie budowania, ale AFAIK nie jest obsługiwany.

W moim przypadku i moim osobistym podejściem jest prowadzony mały skrypt przy starcie pojemnik, coś jak następuje:

#!/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]" 

ten sposób mój Dockerfile wygląda następująco:

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 jest całe repozytorium, jeśli chcesz się przyjrzeć, aby zrozumieć, w jaki sposób robię rzeczy

Obecnie to działa, ale. .. Jeśli chcę dodać, powiedzmy 20 (liczba losowa) rozszerzeń lub jakiejkolwiek innej funkcji, która może być włączona | wyłącz, wtedy zakończę z 20 niepotrzebnymi ENV (ponieważ Dockerfile nie obsługuje plików .env), których definicja cel zostanie ustawiony na tę flagę, aby skrypt wiedział, co robić, a następnie ...

  • Czy to właściwy sposób?
  • Czy należy użyć do tego celu ENV?

Jestem otwarty na pomysły, jeśli masz inne podejście do osiągnięcia tego celu proszę dać mi znać o tym

+0

Jeśli te rozszerzenia/funkcje różniłyby się w zależności od kompilacji, następnie powinieneś użyć 'ARG', aby ustawić je z różnymi wartościami dla każdej kompilacji używając' --build-arg', i nadal możesz używać wartości domyślnych w pliku Dockerfile. Jeśli użyjesz 'ENV', będziesz musiał edytować plik Dockerfile dla każdej kompilacji, aby ustawić różne wartości –

Odpowiedz

85

Od Dockerfile reference:

  • Dyspozycja ARG definiuje zmienną, że użytkownicy może przekazać build-time do budowniczego za pomocą polecenia budowania dockera, używając flagi --build-arg <varname>=<value>.

  • Instrukcja ENV ustawia zmienną środowiskową <key> na wartość <value>.
    Zmienne środowiskowe ustawione przy użyciu ENV będą zachowane, gdy kontener zostanie uruchomiony z wynikowego obrazu.

Więc jeśli potrzebujesz gromadzeniu czas dostosowywania, ARG jest najlepszym wyborem.
Jeśli potrzebujesz dostosowania w czasie wykonywania (aby uruchomić ten sam obraz z różnymi ustawieniami), ENV jest dobrze dopasowany.

Jeśli chcę dodać powiedzmy 20 (liczba losowa) rozszerzeń lub jakiejkolwiek innej funkcji, które można włączyć | wyłączyć

Biorąc pod uwagę liczbę kombinacji włączeni ENV ustawić te funkcje w czasie wykonywania najlepiej tutaj.

ale można combine both przez:

  • Budowanie wizerunku z konkretnym ARG
  • używając że ARG jako ENV

Oznacza to, że z Dockerfile tym:

ARG var 
ENV var=${var} 

Następnie można zbudować obraz o określonej wartości var w czasie kompilacji (docker build --build-arg var=xxx) lub uruchomić kontener z określoną wartością wykonawczą (docker run -e var=yyy)

+0

Świetnie, ale do tych' ARG' można uzyskać dostęp za pomocą skryptu uruchamianego przy starcie kontenera? Jeśli tak to jak? Czy możesz poprawić swoją odpowiedź, dodając mały przykład na temat tego, jak można uzyskać do nich dostęp ze skryptu Bash? – ReynierPM

+0

@ReynierPM możesz, deklarując w swoim Dockerfile (czas kompilacji), w * dodatku * 'ARG',' ENV var = $ {var} ': zobacz http://stackoverflow.com/a/33936014/6309 . Użyj obu. – VonC

+0

Jeśli użyję twojego podejścia, to bez względu na to, co otrzymam ze zmienną ENV 'var' na kontenerze po uruchomieniu, mam rację? W przeciwnym razie nie podążę za tobą. Zapamiętaj to: skrypt jest kopiowany z lokalnego folderu do kontenera i jest używany podczas inicjalizacji kontenera, dlatego używam ENV zamiast ARG, ponieważ nie wiem, czy kiedy kontener uruchamia ARG wciąż żyje i może być dostępny od wewnątrz skrypt bash. – ReynierPM

Powiązane problemy