Почему systemd не перезапускает Docker-контейнер с Java-сервисом после аварийного завершения приложения?
Я разрабатываю микросервис на Java, упакованный в Docker-образ (на основе OpenJDK 21 (LTS) и Maven), и хочу, чтобы контейнер автоматически перезапускался через systemd при аварийном завершении приложения. Проблема заключается в том, что когда Java-приложение падает, контейнер завершается с кодом 0, и systemd не считает это ошибкой – перезапуска не происходит.
Что я уже попробовал:
- Запустил контейнер вручную через
docker run --rm ...
– в этом случае, при аварии Java-приложения контейнер действительно завершается, но Docker сообщает об успешном завершении. - Поиграл с настройками рестарта в unit-файле, используя параметры
Restart=on-failure
иRestartSec=10s
, но при аварийном завершении контейнера unit остаётся остановленным, так как статус контейнера равен 0 (SUCCESS).
Пример моего unit-файла systemd:
[Unit]
Description=Java GeologyData
After=docker.service
Requires=docker.service
[Service]
# Контейнер запускается с опцией --rm для автоматического удаления после остановки
ExecStart=/usr/bin/docker run --rm --name geodata-service geodata-image
ExecStop=/usr/bin/docker stop geodata-service
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
Проблема:
При аварийном завершении Java-приложения внутри контейнера, Docker завершает работу контейнера с кодом 0, и systemd не инициирует перезапуск. Я подозреваю, что использование флага --rm
и то, как Docker обрабатывает завершение контейнера, приводит к неверной интерпретации статуса.
- Как настроить запуск Docker-контейнера через systemd так, чтобы systemd корректно воспринимал аварийное завершение приложения?
- Стоит ли отказаться от опции
--rm
или применять какие-то дополнительные флаги вdocker run
, чтобы в случае сбоя контейнер завершался с ненулевым кодом? - Есть ли альтернативные способы мониторинга и перезапуска Docker-контейнеров, которые лучше интегрируются с systemd?
- нашёл рекомендации отказаться от
--rm
, но это не решило проблему, так как контейнер всё равно завершается с кодом 0 при аварии Java-приложения. - Логи из
journalctl -u geodata-service
подтверждают, что статус завершения равен SUCCESS, что мешает systemd выполнить перезапуск.
Буду благодарен за помощь и примеры unit-файлов или альтернативных подходов, которые помогут перезапускать сервис в случае его аварийного завершения.