Если вы уже освоились в Docker и начали пользоваться различными существующими образами и создавать контейнеры для своих нужд, то наверняка заметили, что контейнеры не перезапускаются сами по себе после перезагрузки системы и пришли к такому же вопросу, которым не так давно задавался и я: “Как сделать так, чтобы контейнер работал постоянно?“. В этой статье мы рассмотрим автоматический перезапуск контейнеров средствами Docker, а также дополнительный способ контроля их работы с помощью простенького скрипта и планировщика Cron.
Перезапуск контейнеров средствами Docker
Docker предоставляет политики перезапуска контейнеров, но по умолчанию контейнеры не перезапускаются даже при перезагрузке системы (перезапуске демона Docker). Политику перезапуска можно указать с помощью флага --restart
и он может принимать одно из следующих значений:
no
– не перезапускать контейнер автоматически (значение по умолчанию)on-failure[:макс-попыток]
– перезапускать контейнер автоматически, если он завершается с кодом, отличным от нуля (то есть с ошибкой). По желанию, здесь можно также указать максимальное кол-во попыток перезапуска контейнера демоном, указывается через двоеточие.always
– всегда перезапускать контейнер. Однако контейнер, остановленный вручную (черезdocker stop
), будет перезапущен автоматически только после перезагрузки системы (перезапуска демона Docker)unless-stopped
– то же самое что иalways
, за исключением того, что контейнер, остановленный вручную, не будет перезапущен даже после перезапуска демона Docker.
Приведу несколько примеров запуска контейнера с использованием этого флага.
Предположим, что у вас уже есть загруженные образы, которые вы хотите использовать и вам известен ID или имя образа, для примера пусть это будет httpd
. О том, как загружать образы и запускать контейнеры, я рассказал в этой статье.
Первый запуск контейнера с помощью docker run:
docker run --restart on-failure:5 httpd
С помощью этой команды будет создан и запущен контейнер из образа httpd, который будет автоматически перезапускаться, если завершится с ошибкой. Попыток перезапуска будет 5.
docker run --restart unless-stopped httpd
С помощью этой команды будет создан и запущен контейнер из образа httpd, который будет перезапускаться автоматически, но не будет перезапускаться, если был остановлен вручную с помощью docker stop
. Как по мне – это наиболее подходящий вариант.
Обновление существующих контейнеров:
Если контейнер из образа у вас уже создан и допустим вы указали ему имя httpd, то вы можете добавить к нему политику перезапуска с помощью команды docker update
:
docker update --restart unless-stopped httpd
Иногда в интернете пишут, что --restart
перезапускает контейнеры только после перезагрузки системы. Но это не правда. В помощью этой политики контейнеры перезапускаются автоматически сразу после падения и конечно после перезагрузки системы тоже.
Контроль и перезапуск контейнера с помощью скрипта
Если у вас возникнут проблемы с использованием политик перезапуска контейнеров, которые предоставляет Docker или вы хотите сделать дополнительную проверку помимо этих политик, вы можете воспользоваться следующим способом:
Создайте скрипт, например httpd_check.sh
со следующим содержимым:
#!/bin/bash
if(( $(docker ps --filter name=httpd --filter status=running --filter status=restarting | wc -l) == 1))
then
docker start httpd
exit 0
fi
Этот скрипт будет искать контейнер httpd, который не находится в статусе running (up) или restarting и выполнять для него обычный запуск с помощью docker start
.
Добавляем права на запуск:
sudo chmod +x check.sh
Вам останется только добавить в cron примерно следующее:
* * * * * alex cd /home/alex && ./httpd_check.sh
Только замените имя пользователя и путь на ваши. На этом у меня все. Удачи!