Если вы можете структурировать вещи так, чтобы ваши изображения были автономными, то вы можете получить довольно короткое время простоя.
Я бы рекомендовал использовать уникальный тег для ваших изображений. Штамп с датой работает хорошо; Вы упоминаете, что у вас есть монорепо, поэтому вы можете использовать идентификатор фиксации в этом репо и для своего тега изображения. В вашем docker-compose.yml
файле используйте переменную окружения для имен изображений
version: '3'
services:
frontend:
image: myname/frontend:${TAG:-latest}
ports: [...]
et: cetera
Не не используйте volumes:
для перезаписи кода в ваших изображениях. Сделайте так, чтобы ваша система CI проверила ваши изображения как встроенные, запустив именно тот образ, который вы собираетесь развернуть; нет привязных креплений или дополнительного искусственного тестового кода. В вопросе упоминается "npm build
внутри контейнеров"; выполните все эти шаги сборки на этапе docker build
и укажите их в своем Dockerfile, чтобы вам не нужно было запускать их во время развертывания.
Если у вас есть новый коммит в вашем репо, постройте новый картинки. Это может произойти в отдельной системе; это может происходить параллельно с вашей работающей системой. Если вы используете уникальный тег для каждого изображения, становится более очевидным, что вы создаете новое изображение, отличное от рабочего изображения. (В принципе, вы можете использовать один тег ...:latest
, но я бы не рекомендовал его.)
# Choose a tag; let's pick something based on a timestamp
export TAG=20200117.01
# Build the images
docker-compose build
# Push the images to a repository
# (Recommended; required if you're building somewhere
# other than the deployment system)
docker-compose push
Теперь вы находитесь в точке, где вы создали новые изображения , но вы все еще используете контейнеры на основе старых изображений. Вы можете сказать Docker Составить, чтобы обновить вещи сейчас. Если вы docker-compose pull
изображения заранее (или если вы создали их в той же системе), то это просто остановка существующих контейнеров и запуск новых. Это единственная точка простоя.
# Name the tag you want to deploy (same as above)
export TAG=20200117.01
# Pre-pull the images
docker-compose pull
# ==> During every step up to this point the existing system
# ==> is running undisturbed
# Ask Compose to replace the existing containers
# ==> This command is the only one that has any downtime
docker-compose up -d
(Почему важен уникальный тег? Скажите, что произошла ошибка, и сборка 20200117.02 имеет критическую ошибку. Очень легко вернуть тег к более раннему 20200117.01 и перезапустите развертывание, поэтому выполните откат развернутой системы, не выполняя git revert
и не перестраивая код. Если вы смотрите на менеджеры кластеров, такие как Kubernetes, то значение измененного тега является сигналом для объекта развертывания Kubernetes, что что-то обновило , так что это вызывает автоматическое c перераспределение.)