middle
Как запустить Java-приложение как systemd-сервис?
Создание systemd-сервиса позволяет Java-приложению запускаться автоматически при загрузке, перезапускаться при сбоях и управляться стандартными инструментами.
Шаг 1. Подготовка
Пример
# Создать пользователя для приложения (без оболочки)
sudo useradd -r -s /usr/sbin/nologin appuser
# Создать каталог и скопировать приложение
sudo mkdir -p /opt/myapp
sudo cp application.jar /opt/myapp/
# Установить права
sudo chown -R appuser:appuser /opt/myapp
Шаг 2. Создание unit-файла
Полный unit-файл /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot Application
Documentation=https://example.com
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=appuser
Group=appuser
WorkingDirectory=/opt/myapp
# Файл с переменными окружения
EnvironmentFile=/opt/myapp/.env
# Команда запуска
ExecStart=/usr/bin/java ${JAVA_OPTS} -jar /opt/myapp/application.jar
# Корректная остановка (SIGTERM -> Spring Boot graceful shutdown)
ExecStop=/bin/kill -SIGTERM $MAINPID
SuccessExitStatus=143
# Перезапуск при сбоях
Restart=on-failure
RestartSec=10
# Таймауты
TimeoutStartSec=60
TimeoutStopSec=30
# Логирование в journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
# Безопасность
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/myapp/logs
[Install]
WantedBy=multi-user.target
Шаг 3. Запуск и управление
Пример
sudo systemctl daemon-reload # Перечитать конфигурацию systemd
sudo systemctl start myapp # Запустить
sudo systemctl status myapp # Проверить статус
journalctl -u myapp -f # Посмотреть логи
sudo systemctl enable myapp # Включить автозапуск
Ключевые параметры
SuccessExitStatus=143— код 143 = 128 + 15 (SIGTERM). Spring Boot завершается с этим кодом при корректной остановке. Без этого systemd считает это ошибкойRestart=on-failure— перезапуск только при аварийном завершении (не приsystemctl stop)ProtectSystem=strict— файловая система только для чтения, кромеReadWritePathsNoNewPrivileges=true— процесс не может повысить привилегии
На собеседовании: это практический вопрос, который показывает опыт деплоя. Ключевое — знать
SuccessExitStatus=143иRestart=on-failure. Частая ошибка — запускать приложение от root или забытьdaemon-reloadпосле изменения unit-файла.