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 файла

  • пусть контейнер продолжает работать на корме


?

641   2  

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 из самого образа приложения и вместо этого использует первый этап для установки зависимостей в другом контексте и копирования их в конечный образ.

Сейчас, во время разработки у тебя есть несколько вариантов. На основе вашей команды docker-compose.yml создается впечатление, что вы монтируете приложение в контейнер как .:/var/www/root. Вы можете добавить composer сервис к вашему docker-compose.yml аналогично моему примеру в https://gist.github.com/andyshinn/e2c428f2cd234b718239 . Здесь вы просто делаете docker-compose run --rm composer install, Когда вам нужно обновить зависимости локально (это сохраняет построение зависимостей внутри контейнера, что может иметь значение для собственных скомпилированных расширений, особенно если вы развертываете как контейнеры и разработка на Windows или Mac).

Другой вариант-просто сделать что-то похожее на то, что уже предложил Крис, и использовать официальный образ Composer для обновления и управления зависимостями, когда это необходимо. Я уже делал что-то подобное локально, где у меня были частные зависимости от GitHub, которые требовали аутентификации SSH:
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

    Ничего не найдено.