Решение состоит в том, чтобы разделить composer часть на 2 отдельных блока:
Блок 1 из composer инструкций
Часть, которая загружает пакеты. Это может выполняться внутри «компоновщика».
Блок 2 из composer инструкций
Часть, которая использует загруженные пакеты для прогрева системы. Это можно запустить в работающем контейнере, который будет запускаться «на месте» с учетом среды и доступа к соответствующим службам поддержки.
Реализация
Dockerfile
Таким образом, я изменил команду RUN
в моем Dockerfile с
RUN \
cd /files/tighten-violet && \
composer --no-ansi --no-interaction install --no-progress --no-autoloader --no-scripts && \
composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
composer --no-ansi --no-interaction run-script --no-dev symfony-scripts && \
php bin/console cache:clear && \
php bin/console cache:clear --env=prod && \
php bin/console assetic:dump --env=prod && \
:
на
RUN \
cd /files/tighten-violet && \
composer --no-ansi --no-interaction install --no-progress --no-autoloader --no-scripts && \
:
ie: я удалил все, кроме «загрузки пакетов в / vendor ", так как" загрузка "не зависит от переменных среды или конфигурации.
Здесь у меня есть отправляемое docker изображение с уже заполненным /vendor
.
Но все еще пропущен один шаг ... где эти пропущенные строки go?
bootstrap. sh
То, что я сделал, это bootstrap скрипт, поэтому я изменил CMD строка из
CMD [ "apachectl", "-D", "FOREGROUND" ]
в
CMD [ "/files/bootstrap.sh" ]
Файл boostrap.sh
также копируется в процессе сборки ... и вот содержимое (простая начальная версия):
#!/usr/bin/env bash
# Provision
composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
composer --no-ansi --no-interaction run-script --no-dev symfony-scripts
php bin/console cache:clear && \
php bin/console cache:clear --env=prod && \
php bin/console assetic:dump --env=prod
# Start the server
apachectl -D FOREGROUND
Содержит «установочную часть», которая потенциально может зависит от среды, включая дамп автозагрузки, сценарии SensioBundle, а также кэши и дампы. На всякий случай есть ENV-переменные, которые изменяют поведение, которое мы хотим кэшировать.
Это работает на docker run
. Но если вы выполните docker stop
, а затем docker start
снова, часть подготовки также будет запускаться снова и снова (остановка + запуск не останавливает состояние процесса, как это делает «пауза», он убивает процесс и затем перезапускает его снова, начиная с начала bootstrap.sh
.
Поэтому я мог бы улучшить сценарий boostrap, чтобы он отмечался, если он был автоматически подготовлен. Это улучшенная (и окончательная) вторая версия bootstrap.sh
script:
#!/usr/bin/env bash
provisionIfNeeded()
{
PROVISIONED=/tmp/provisioned
if [ ! -f ${PROVISIONED} ]; then
echo "------------------------------------------------------------------------------"
echo "Provisioning"
echo "------------------------------------------------------------------------------"
composer --no-ansi --no-interaction dump-autoload --no-dev --optimize --classmap-authoritative --no-scripts && \
composer --no-ansi --no-interaction run-script --no-dev symfony-scripts
php bin/console cache:clear && \
php bin/console cache:clear --env=prod && \
php bin/console assetic:dump --env=prod
echo "------------------------------------------------------------------------------"
echo "Ended provisioning"
echo "------------------------------------------------------------------------------"
touch ${PROVISIONED}
fi
}
startServer()
{
echo "Starting httpd."
apachectl -D FOREGROUND
}
provisionIfNeeded
startServer
Итак, после docker run
:
- Сценарий запускается, при необходимости пытается выполнить подготовку.
- Он проверяет флаг.
- Поскольку он не найден, вызывает ли инициализация недостающие строки в Dockerfile.
- В конце инициализации помечает контейнер как подготовленный.
- Затем запускается apache.
И после docker start
:
- Сценарий запускается, пытается выполнить подготовку при необходимости.
- Флаг найден , поэтому никакое обеспечение не выполняется.
- Затем начинается apache.
10 секунд подготовки отнимаются со стадии сборки и переносятся в стадию запуска.
Минусы
Запуск контейнера только в первый раз длится около На 10 секунд больше, чем если бы мы подготовились на этапе сборки.
Плюсы
Контейнер отлично «записан» с кэшами, которые принадлежат каждой из сред выполнения, сохраняя этап сборки через Dockerfile содержит максимальный общий коэффициент для всех сред.
Надеюсь на помощь!