Docker-выполнить команду после монтирования Тома
У меня есть следующий Dockerfile для PHP runtime, основанный на официальном образе [php][1].
FROM php:fpm
WORKDIR /var/www/root/
RUN apt-get update && apt-get install -y
libfreetype6-dev
libjpeg62-turbo-dev
libmcrypt-dev
libpng12-dev
zip
unzip
&& docker-php-ext-install -j$(nproc) iconv mcrypt
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
&& docker-php-ext-install -j$(nproc) gd
&& docker-php-ext-install mysqli
&& docker-php-ext-enable opcache
&& php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
&& php composer-setup.php
&& php -r "unlink('composer-setup.php');"
&& mv composer.phar /usr/local/bin/composer
У меня проблемы с бегом composer install.
Я предполагаю, что Dockerfile запускается до монтирования Тома, потому что я получаю composer.json файл не найден ошибка при добавлении:
...
&& mv composer.phar /usr/local/bin/composer
&& composer install
К вышесказанному.
Но, добавив следующее свойство к docker-compose.yml:
command: sh -c "composer install && composer require drush/drush"
Завершает работу контейнера после завершения выполнения команды.
Есть ли способ кому:
- дождитесь монтирования Тома
- запустите
composer installс помощью смонтированногоcomposer.jsonфайла - пусть контейнер продолжает работать на корме
?
2 ответов:
Я в целом согласен с ответом Криса на вопрос о местном развитии. Я собираюсь предложить что-то, что сочетается с недавней функцией Docker, которая может задать путь для выполнения как локальной разработки, так и последующего производственного развертывания с одним и тем же образом.
Давайте начнем с образа, который мы можем построить таким образом, чтобы его можно было использовать либо для локальной разработки, либо для развертывания где-то, содержащего код и зависимости. В последней версии Docker (17.05) появилась новая многоступенчатая функция сборки, которой мы можем воспользоваться. В этом случае мы можем сначала установить все ваши зависимости Composer в папку в контексте сборки, а затем скопировать их в конечный образ без необходимости добавлять Composer в конечный образ. Это может выглядеть следующим образом:FROM composer as composer COPY . /app RUN composer install --ignore-platform-reqs --no-scripts FROM php:fpm WORKDIR /var/www/root/ RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng12-dev \ zip \ unzip \ && docker-php-ext-install -j$(nproc) iconv mcrypt \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install mysqli \ && docker-php-ext-enable opcache COPY . /var/www/root COPY --from=composer /app/vendor /var/www/root/vendorЭто удаляет весь Composer из самого образа приложения и вместо этого использует первый этап для установки зависимостей в другом контексте и копирования их в конечный образ.
Сейчас, во время разработки у тебя есть несколько вариантов. На основе вашей команды
Другой вариант-просто сделать что-то похожее на то, что уже предложил Крис, и использовать официальный образ Composer для обновления и управления зависимостями, когда это необходимо. Я уже делал что-то подобное локально, где у меня были частные зависимости от GitHub, которые требовали аутентификации SSH:docker-compose.ymlсоздается впечатление, что вы монтируете приложение в контейнер как.:/var/www/root. Вы можете добавитьcomposerсервис к вашемуdocker-compose.ymlаналогично моему примеру в https://gist.github.com/andyshinn/e2c428f2cd234b718239 . Здесь вы просто делаетеdocker-compose run --rm composer install, Когда вам нужно обновить зависимости локально (это сохраняет построение зависимостей внутри контейнера, что может иметь значение для собственных скомпилированных расширений, особенно если вы развертываете как контейнеры и разработка на Windows или Mac).docker run --rm --interactive --tty --volume $PWD:/app:rw,cached --volume $SSH_AUTH_SOCK:/ssh-auth.sock --env SSH_AUTH_SOCK=/ssh-auth.sock --volume $COMPOSER_HOME:/composer composer:1.4 install --ignore-platform-reqs --no-scriptsЧтобы резюмировать, обоснование этого метода построения образа и установки зависимостей Composer с помощью внешнего контейнера / обслуживание:
- зависимости для конкретной платформы будут построены правильно для контейнера (архитектура Linux против Windows или Mac).
- никакой Composer или PHP не требуется на вашем локальном компьютере (все это содержится в Docker и Docker Compose).
- созданный вами исходный образ может быть запущен и развернут без необходимости монтирования в него кода. В процессе разработки вы просто переопределяете папку
/var/www/rootлокальным Томом.
Если это для общей среды разработки, то намерение не совсем идеально, потому что оно связывает приложение с конфигурацией Docker.
Просто запустите
composer installотдельно каким-либо другим способом (для этого есть изображение на dockerhub, которое позволяет вам просто сделать(docker run -it --rm -v $(pwd):/app composer/composer install).
Но да, возможно, Вам понадобится последняя строка в
Dockerfile, чтобы бытьbash -c "composer install && php-fpm".
- дождитесь монтирования Тома
Нет, Тома не могут быть смонтированы во время процесса сборки docker. Хотя вы можете скопировать исходный код.
- запустите composer install с помощью смонтированного composer.JSON-файл
Нет, см. ответ выше.
- пусть контейнер продолжает работать после
Да, вам нужно будет выполнить
php-fpm --nodaemonize(что является длительным процессом, поэтому он не завершится.
Comments