Как я автоматизировала перезапуск сервисов на VPS с помощью systemd (и почему без этого нельзя)

ГлавнаяКак я автоматизировала перезапуск сервисов на VPS с помощью systemd (и почему без этого нельзя)

Содержание

Однажды у меня на проде «упал» процесс, и это случилось как раз в пятницу вечером — конечно же, я уже отключилась от работы. Сайт, завязанный на этом процессе, просто перестал отвечать. И всё это время, пока я пила чай и смотрела сериал, никто не понимал, что случилось. В понедельник — ах да, извините, забыли поставить авто‑перезапуск в systemd. Больше таких ситуаций я себе не позволяла.

Сегодня расскажу, как настроить auto-healing на VPS с помощью systemd, чтобы сервисы сами восстанавливались при сбоях. Подойдёт для Ubuntu, Debian, CentOS — везде, где есть systemd.


Зачем вообще нужен auto-healing?

Если приложение или скрипт внезапно упал, а вы об этом узнаёте спустя сутки — это упущенные пользователи, ошибки в логах и стресс. Особенно если VPS используется для:

  • микросервисов,
  • веб-серверов (nginx, Apache),
  • прокси,
  • Telegram-ботов,
  • VPN-сервисов (WireGuard, OpenVPN),
  • cron-скриптов.

Решение — systemd restart on failure и несколько строчек, которые буквально спасают прод.


Пример из моей практики: auto-restart для Node.js

У меня был простой сервис на Node.js, который обрабатывал API-запросы. Иногда он крашился при особых типах данных, пока я не нашла баг. Чтобы не ждать, пока я починю всё, я добавила auto-restart в его юнит:

[Unit]
Description=My Node.js API
After=network.target

[Service]
ExecStart=/usr/bin/node /home/myuser/my-api/index.js
Restart=on-failure
RestartSec=5
StartLimitBurst=3
StartLimitIntervalSec=60
User=myuser
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Сохраняем файл как /etc/systemd/system/my-api.service.

Теперь, если процесс “падает”, systemd перезапускает его через 5 секунд. А если он упадёт 3 раза за минуту — перезапуск приостанавливается (защита от бесконечного цикла).


Расшифровка параметров:

  • Restart=on-failure — перезапускать, если процесс завершился с ошибкой.
  • RestartSec=5 — ждать 5 секунд перед перезапуском.
  • StartLimitBurst=3 и StartLimitIntervalSec=60 — максимум 3 перезапуска за 60 секунд.
  • ExecStart — путь до исполняемого файла.

Также поддерживаются другие значения Restart, например:

ПараметрЧто означает
noНе перезапускать (по умолчанию)
alwaysПерезапускать всегда, даже при exit 0
on-failureТолько если завершилось с ошибкой
on-abnormalТолько при сигнале или core dump
on-watchdogПри watchdog timeout
on-abortТолько если завершено сигналом

Как отследить ошибки: systemctl и логи

После настройки можно наблюдать поведение:

sudo systemctl status my-api

Если хотите увидеть, почему сервис «упал» — смотрим:

journalctl -u my-api

Если сервис упал слишком часто, и systemd его «заморозил», нужно сбросить счётчик:

sudo systemctl reset-failed my-api

Ещё примеры из жизни

Telegram-бот

[Service]
ExecStart=/usr/bin/python3 /home/user/bot/main.py
Restart=always
RestartSec=10

WireGuard туннель

[Service]
ExecStart=/usr/bin/wg-quick up wg0
ExecStop=/usr/bin/wg-quick down wg0
Restart=on-failure
RestartSec=3

Прокси на Go

[Service]
ExecStart=/usr/local/bin/myproxy
Restart=always
RestartSec=5
User=proxyuser

systemd health-check (ждём как родного)

Если вы хотите ещё более продвинуто — можно настроить WatchdogSec и использовать NotifyAccess=all, чтобы приложение «пинговало» systemd и показывало, что оно живо. Но это уже для тех, кто пишет свои сервисы с sd_notify.


Вопрос: а что если VPS ребутнулся?

Тогда просто добавьте:

[Install]
WantedBy=multi-user.target

И выполните:

sudo systemctl enable my-api

Теперь сервис запустится при старте системы.


В результате…

Если бы мне кто-то сказал ещё на старте моей практики, что одна строчка Restart=on-failure избавит от десятков часов головной боли… я бы настроила её везде сразу. Теперь на всех VPS, где у меня крутятся сервисы, я обязательно прописываю auto-restart через systemd. Это просто, надёжно и по-настоящему спасает.