Помогите разобраться в вопросе деплоя php приложения которое работает в dockere. Есть например php приложение, есть его код в каком нибудь version control system, приложение имеет n инстансов, которые могут размещаться на разных серверах. Имеется какой-то свой docker image в котором устанавливается php-fpm определенной версии, различные php extension необходимые для функционирование приложения. И если мы хотим настроить автодеплой при помощи какого либо CI\CD tools(Jenkins, Gitlab CI\CD etc), правильно ли я понимаю алгоритм и процесс как это должно происходить?
В нашем CI\CD pipeline, который сперва делает checkout нужной нам ветки из VCS, далее мы билдим контейнер с php(код php в контейнер попадает путем COPY команды), далее выполняем composer install(так как vendor папку не храним в VCS), далее запускаем тесты\анализаторы кода и тд, если проверки прошли успешно делаем docker push в какой либо registry(docker, gitlab etc), правильно ли понимаю что в registry пушим образ в котором кроме самого php-fpm и его extension, должен присутствовать код приложения (с vendor и тд)? Далее на целевых серверах делаем docker pull только что созданного образа и docker run.
Alexey Dmitriev, Работать будет и если через ftp архив с кодом загружать, вопрос в том насколько мной описаный алгоритм соответствует devops практикам и best practices по использованию docker
Markusam, полностью соответствует, только есть нюанс с docker pull на серверах, из-за рестарта контейнера у тебя будет downtime, стоит подумать над использованием какого либо оркестратора контейнеров
Надо не забыть про миграции БД и откат миграций в случае если pipeline упадёт с ошибкой.
А ещё могут понадобится фоновые процессы, например обработчики очередей или запускать что-то через cron.
А ещё могут понадобится фоновые процессы, например обработчики очередей или запускать что-то через cron.
На практике сталкивался только с тем что всякие фоновые процессы помещали обычно в тот же контейнер что и веб приложении и за процессом обычно присматривал supervisor. Насколько знаю это не совсем правильная практика, рекомендуются под каждый процесс по контейнеру. А не будет ли это слишком накладно по ресурсам? И насколько понимаю тогда под фоновые процессы надо создавать отдельный docker image(php-cli) Надо ли в связи с этим тогда переделывать архитектуру приложения?
Это типичный вариант развёртывания приложения в докере. Единственный его минус - некоторое время даунтайма между моментом когда опустился старый контейнер и поднялся новый. Для решения этой проблемы есть разные техники. Например, blue-green deployment. Это когда есть два контейнера, условно называемые green и blue. И трафик льётся только на один. Скажем, на green. В момент деплоя обновляется blue контейнер и после того как он полностью будет готов - переключаем трафик на blue. В следующий раз деплой начнётся с обновления green.
Переключение трафика делается разными способами. Самый безопасный - переписать конфиг nginx и релоаднуть его. Или менее безопасный, зато без необходимости править конфиг, - добавить оба конейнера в одну upstream группу и опустить green контейнер после обновления blue.
Довольно муторное дело. Но в оркестраторах типа openshift и kubernetes такой деплоймент процесс уже встроен из коробки. Но вот сами оркестраторы довольно тяжелая штука. Для них нужен отдельный выделенный человек, который будет заниматься только ими. Так что я советую начинать присматриваться к оркестраторам только когда количество серваков перевалит за 50. С меньшим количеством это просто нерентабельно.
Другой вариант развёртывания - контейнер с пхп поднят постоянно, но код проекта монтируется в контейнер через volume. Далее ci джоба по sftp заливает новый код в соседнюю папку и переключает симлинк. Симлинк переключается атомарно и контейнер сразу начинает работать с новым кодом. Ничего больше делать не надо. Я рекомендую такой подход когда на проекте менее 50 серверов.
Vamp, вы читали про разные подходы? Если нет, то Почитайте про подход start-first / stop-first для сворма. Работает не идеально, но суть именно в бесшовном деплое. И основная проблема в том, что мы сами должны задать корректный healthcheck для каждого окружения, а это порой долго и муторно. Кубер умнее, бесспорно.
Дмитрий, воу, полегче. Вы написали только про healthcheck, который сам по себе к бесшовному деплою никакого отношения не имеет. А вот start-first / stop-first имеет. Надо было сразу про это написать.
А wait-for-it.sh в docker (compose) по-прежнему сам по себе никак не влияет на бесшовный деплоймент. Более того, я об этом даже в ответе упоминал: "и после того как он полностью будет готов". wait-for-it.sh и healthcheck решают только одну вот эту маленькую задачу из цитаты. А по вашему комментарию складывается впечатление, что достаточно только хелс чек настроить и всё, атомарный деплой обеспечен.
В целом все правильно.
Насчет деплоя - есть нюансы
- как CD pipeline знает адреса серверов? В современном "облачном" окружении они часто меняются, нужен какой-то метод для их динамического получения
- как обеспечить бесперебойную работу приложения во время деплоя?
В облаках (AWS/GCP/ наверно и Yandex) есть managed services, которые сами умеют решать эти и другие (autoscaling) проблемы. В AWS это ECS, Elastic Beanstalk, AWS App Runner, managed K8S.
как CD pipeline знает адреса серверов? В современном "облачном" окружении они часто меняются, нужен какой-то метод для их динамического получения
В самом скрипте pipeline адрес сервера можно записать как переменную и при деплое(тогда это должен быть по идеи отдельный pipeline?) передавать это значение, ну это если адреса не меняются динамически.
как обеспечить бесперебойную работу приложения во время деплоя?
Ну это тогда надо внедрять green\blue deployment?
Либо как я понимаю ответом на все это есть как вы указали managed services? Но это при использовании клауд решений(если какой нибудь hetzner брать то там такого может не быть?)
P.S. Прошу прощения за возможно глупые вопросы, потому что в devops практиках не гуру
Да, если адреса постоянные их можно сохранять в конфигурации CI.
Ну это тогда надо внедрять green\blue deployment?
Это проще чем green\blue - исключаем сервер из лоадбалансинге, деплоим, проверяем, включаем.
Либо как я понимаю ответом на все это есть как вы указали managed services? Но это при использовании клауд решений(если какой нибудь hetzner брать то там такого может не быть?)
Нет единственно правильного решения. managed services удобнее, но дороже, плюс не всегда возможно по разным причинам.
В целом, как уже написали в комментах, стоит посмотреть на оркестраторы контейнеров - Kubernetes или другие.