To może być trywialne pytanie, ale czytanie dokumentacji dla ARG i ENV nie wyjaśnia mi sprawy.
Buduję kontener PHP-FPM i chcę dać możliwość włączania / wyłączania niektórych rozszerzeń na potrzeby użytkownika.
Byłoby wspaniale, gdyby można to zrobić w pliku Dockerfile, dodając warunki warunkowe i przekazując flagi w poleceniu kompilacji, być może, ale AFAIK nie jest obsługiwany.
W moim przypadku i moim osobistym podejściem jest uruchomienie małego skryptu podczas uruchamiania kontenera, coś takiego:
#!/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 "$@"
Tak Dockerfile
wygląda mój wygląd:
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
Oto całe repozytorium, jeśli potrzebujesz dokładniejszego przyjrzenia się, aby zrozumieć, jak robię rzeczy
Obecnie to działa, ale ... Jeśli chcę dodać, powiedzmy, 20 (losową liczbę) rozszerzeń lub jakąkolwiek inną funkcję, którą można włączyć | wyłączyć, skończę z 20 niepotrzebnymi ENV
(ponieważ Dockerfile nie obsługuje .env files), której jedynym celem byłoby ustawienie tej flagi, aby skrypt wiedział, co wtedy zrobić ...
- Czy to jest właściwy sposób?
- Powinienem używać
ENV
do tego celu?
Jestem otwarty na pomysły, jeśli masz inne podejście do osiągnięcia tego celu, daj mi o tym znać
źródło
ARG
aby ustawić dla nich różne wartości przy każdej kompilacji--build-arg
, i nadal można używać wartości domyślnych w pliku Dockerfile. Jeśli używaszENV
, musisz edytować sam plik Dockerfile dla każdej kompilacji, aby ustawić inne wartościOdpowiedzi:
Z odwołania do Dockerfile :
Więc jeśli potrzebujesz dostosowania czasu budowy ,
ARG
jest to najlepszy wybór.Jeśli potrzebujesz dostosowania w czasie wykonywania (aby uruchomić ten sam obraz z różnymi ustawieniami),
ENV
jest dobrze dopasowany.Biorąc pod uwagę liczbę kombinacji,
ENV
w tym przypadku najlepiej jest użyć do ustawienia tych funkcji w czasie wykonywania.Ale możesz połączyć oba przez:
ARG
ARG
jako plikuENV
Oznacza to, że z plikiem Dockerfile zawierającym:
Następnie możesz zbudować obraz z określoną
var
wartością w czasie kompilacji (docker build --build-arg var=xxx
) lub uruchomić kontener z określoną wartością w czasie wykonywania (docker run -e var=yyy
)źródło
ARG
można uzyskać do nich dostęp ze skryptu, który uruchamiam podczas uruchamiania kontenera? Jeśli tak to jak? Czy mógłbyś poprawić swoją odpowiedź, dodając mały przykład o tym, jak można uzyskać do nich dostęp ze skryptu bash?ARG
AnENV var=${var}
: patrz stackoverflow.com/a/33936014/6309 . Użyj obu.var
zmienną ENV na kontenerze, gdy zacznie, mam rację? W przeciwnym razie w ogóle cię nie śledzę. Pamiętaj: skrypt jest kopiowany z folderu lokalnego do kontenera i jest używany podczas inicjalizacji kontenera, dlatego używam ENV zamiast ARG, ponieważ nie wiem, czy po uruchomieniu kontenera ARG wciąż żyje i można uzyskać do niego dostęp od wewnątrz skrypt bash.Więc jeśli chcesz ustawić wartość zmiennej środowiskowej na coś innego dla każdej kompilacji, możemy przekazać te wartości w czasie kompilacji i nie musimy za każdym razem zmieniać naszego pliku docker.
Podczas gdy
ENV
raz ustawione nie można nadpisać wartościami wiersza poleceń. Tak więc, jeśli chcemy, aby nasza zmienna środowiskowa miała różne wartości dla różnych kompilacji, możemy użyćARG
i ustawić wartości domyślne w naszym pliku docker. A kiedy chcemy nadpisać te wartości, możemy to zrobić za pomocą--build-args
każdej kompilacji bez zmiany naszego pliku docker.Aby uzyskać więcej informacji, można odwołać się w tym .
źródło