Может ли Docker-контейнер самостоятельно перезапускаться?

Ответ

Да, Docker-контейнер может быть настроен на автоматический перезапуск при помощи политики перезапуска (restart policy). Это базовая, но критически важная функция для обеспечения отказоустойчивости сервисов в production-среде. Я настраиваю её практически для всех долгоживущих контейнеров (веб-серверы, базы данных, брокеры сообщений).

Доступные политики и сценарии их использования в моей практике:

  • no (по умолчанию): Контейнер не перезапускается никогда. Использую только для одноразовых задач или отладки.
  • on-failure[:max-retries]: Самый частый выбор. Контейнер перезапускается, если он завершился с ошибкой (ненулевой код выхода). Можно указать максимальное число попыток. Идеально для обработчиков задач (workers), которые могут падать из-за временных ошибок.
    docker run -d --restart=on-failure:5 my-worker-image
  • unless-stopped: Основной выбор для production-сервисов. Контейнер всегда перезапускается, если он не был явно остановлен командой docker stop. После перезагрузки хоста Docker демон автоматически запустит такие контейнеры. Это гарантирует, что сервис будет работать после сбоя системы.
    docker run -d --name nginx --restart=unless-stopped -p 80:80 nginx:alpine
  • always: Контейнер перезапускается всегда, даже после ручной остановки. Использую с осторожностью, так как это может привести к неожиданному поведению. Обычно заменяю на unless-stopped.

Важные технические детали:

  • Политика применяется при использовании docker run. Для уже запущенного контейнера её можно изменить командой:
    docker update --restart=unless-stopped <container_name>
  • Перезапуск осуществляется демоном Docker, а не изнутри контейнера. Если сам Docker демон не запущен, перезапуск не произойдёт — для этого нужен внешний оркестратор (systemd, k8s).
  • При перезапуске с always или unless-stopped порядок запуска контейнеров не гарантирован. Для зависимостей (например, БД должна запуститься до приложения) нужно использовать health checks и логику ожидания в entrypoint-скриптах или оркестраторы вроде Docker Compose (depends_on) и Kubernetes.

Ответ 18+ 🔞

Слушай, а то некоторые думают, что Docker-контейнер, как одноразовый стаканчик — упал и всё. Нет, блядь, его можно заставить автоматически перезапускаться, если что. Это называется политика перезапуска (restart policy). Без неё в продакшене делать нихуя, если, конечно, ты не любишь в три часа ночи вскакивать от алертов. Я эту штуку ставлю на всё, что должно работать долго — веб-серверы, базы, брокеры.

Вот какие бывают политики и где я их юзаю:

  • no (по дефолту): Не перезапускается вообще. Ну, ёпта, это для отладки или одноразовых скриптов, которые сдохли и похуй.
  • on-failure[:max-retries]: Мой самый частый выбор, ебать копать. Контейнер встаёт как ни в чём не бывало, только если он сдох с ошибкой (код выхода не ноль). Можно даже указать, сколько раз пытаться — типа пять. Идеально для воркеров, которые могут временно обосраться.
    docker run -d --restart=on-failure:5 my-worker-image
  • unless-stopped: А это уже для серьёзных продакшен-сервисов. Контейнер перезапускается всегда, если ты его сам вручную не прибил через docker stop. Даже если весь сервер перезагрузился — демон Docker его поднимет. Гарантия, что сервис будет жить после любого пиздеца.
    docker run -d --name nginx --restart=unless-stopped -p 80:80 nginx:alpine
  • always: Перезапускается ВСЕГДА, даже если ты его сам остановил. С этим надо аккуратнее, а то он тебе начнёт жить своей жизнью, как маньяк. Я обычно заменяю на unless-stopped, чтобы не было сюрпризов.

Теперь важные детали, а то народ обосрётся:

  • Политику задаёшь при запуске через docker run. Если контейнер уже бежит, а ты проебался — можно поправить на ходу:
    docker update --restart=unless-stopped <container_name>
  • Перезапускает всё это дело сам демон Docker, а не какая-то магия из контейнера. Если демон сдох — то и перезапуска не будет, тут уже нужен внешний надсмотрщик вроде systemd или k8s.
  • И главное, запомни: если используешь always или unless-stopped, то порядок запуска контейнеров — это лотерея. Может так выйти, что твоё приложение запустится раньше базы данных и нихуя не заработает. Для таких зависимостей нужны health checks, умные entrypoint-скрипты с ожиданием или нормальные оркестраторы вроде Docker Compose (там есть depends_on) или Kubernetes. А то будет тебе хиросима, а не кластер.