Почему systemd не перезапускает Docker-контейнер с Java-сервисом после аварийного завершения приложения?

Рейтинг: 1Ответов: 0Опубликовано: 03.03.2025

Я разрабатываю микросервис на 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 обрабатывает завершение контейнера, приводит к неверной интерпретации статуса.

  1. Как настроить запуск Docker-контейнера через systemd так, чтобы systemd корректно воспринимал аварийное завершение приложения?
  2. Стоит ли отказаться от опции --rm или применять какие-то дополнительные флаги в docker run, чтобы в случае сбоя контейнер завершался с ненулевым кодом?
  3. Есть ли альтернативные способы мониторинга и перезапуска Docker-контейнеров, которые лучше интегрируются с systemd?
  • нашёл рекомендации отказаться от --rm, но это не решило проблему, так как контейнер всё равно завершается с кодом 0 при аварии Java-приложения.
  • Логи из journalctl -u geodata-service подтверждают, что статус завершения равен SUCCESS, что мешает systemd выполнить перезапуск.

Буду благодарен за помощь и примеры unit-файлов или альтернативных подходов, которые помогут перезапускать сервис в случае его аварийного завершения.

Ответы

Ответов пока нет.