Как настроить перезапуск контейнера при ошибке

Ответ

В Docker политика перезапуска контейнера задается флагом --restart. Я использую её для обеспечения отказоустойчивости сервисов.

Доступные политики:

  • no (по умолчанию) – не перезапускать.
  • on-failure[:max-retries] – перезапускать только при завершении с ненулевым кодом выхода (ошибка). Можно указать максимальное количество попыток.
  • unless-stopped – перезапускать всегда, кроме случаев, когда контейнер был явно остановлен командой docker stop. Это мой основной выбор для production-сервисов.
  • always – перезапускать всегда, даже после docker stop. Использую редко, так как это может привести к неожиданному поведению.

Пример запуска с политикой перезапуска:

docker run -d --name my-app --restart=unless-stopped -p 80:80 nginx

В Docker Compose политика указывается в секции сервиса:

services:
  web:
    image: nginx:alpine
    restart: unless-stopped

Диагностика: Количество перезапусков контейнера можно проверить командой:

docker inspect --format='{{.RestartCount}}' <container_name>

Для тонкой настройки также можно использовать --restart-delay, чтобы задать паузу между попытками перезапуска.

Ответ 18+ 🔞

Эй, а вот это реально полезная штука, про которую многие забывают, пока их сервис не накрылся медным тазом посреди ночи. Смотри, в Docker есть такая опция --restart, она как раз для того, чтобы твой контейнер не сдох навсегда, если что-то пойдёт не так.

Какие есть варианты, чтобы не быть полным распиздяем:

  • no (стоит по умолчанию) – не перезапускать нихуя. Упал и пусть лежит. Для тестов сойдёт.
  • on-failure[:max-retries] – вот это уже умнее. Перезапустит только если контейнер вылетел с ошибкой (код не ноль). Можно даже указать, сколько раз пытаться – on-failure:5. Удобно, если знаешь, что сервис иногда глючит, но бесконечно его воскрешать смысла нет.
  • unless-stopped – а это, бля, мой фаворит для продакшена. Перезапускает всегда, кроме одного случая: если ты сам его прибил командой docker stop. То есть сервис живёт, пока живёт демон Docker, и после перезагрузки всей системы сам поднимется. Красота.
  • always – а вот с этой политикой надо аккуратнее, она перезапускает вообще всегда, даже после твоего явного docker stop. Может получиться ёперный театр, когда ты пытаешься что-то починить, а оно снова и снова встаёт. Используй с пониманием, а то сам от себя охуеешь.

Как это впихнуть в команду:

docker run -d --name my-app --restart=unless-stopped -p 80:80 nginx

Вот и всё, теперь nginx будет как проклятый.

А если ты любитель Docker Compose, то там тоже просто:

services:
  web:
    image: nginx:alpine
    restart: unless-stopped

Ну и наконец, как проверить, не пиздит ли он тебе:
Хочешь узнать, сколько раз твой упрямец уже перезапускался? Вот команда, которая даст ответ:

docker inspect --format='{{.RestartCount}}' <container_name>

А ещё можно --restart-delay добавить, чтобы между попытками была пауза, а не дикая гонка "упал-встал". Иногда сервису надо секунд 10, чтобы отойти от удара, понимаешь?