Службы systemd: systemctl, статус, логи и своя служба для бота

Как управлять службами через systemctl, читать статус и логи через journalctl и оформить скрипт или Telegram-бота как службу с автозапуском и перезапуском после падения. Ubuntu, Debian, AlmaLinux.

20 октября 2026 г.·3 мин чтения·systemd, systemctl, journalctl, linux

Nginx, база данных, Docker и SSH работают на сервере постоянно, сами поднимаются после перезагрузки и перезапускаются, если упали. Всё это делает systemd, а управляют им через systemctl. Та же механика доступна и вашим программам: любой скрипт за пять минут превращается в службу, которая работает круглосуточно без открытого терминала.

Для экспериментов подойдёт любой VPS с Ubuntu или Debian; на tanaka.host сервер можно взять на день-два, пройти инструкцию и удалить без лишних трат.

Как это работает

При загрузке ядро запускает процесс номер 1 — это systemd. Он поднимает всё остальное в правильном порядке и следит за этим до выключения. Каждая служба описана небольшим текстовым файлом — юнитом с расширением .service: какую программу запустить, от чьего имени, после каких других служб и что делать, если она завершилась.

Процесс службы и всё, что он породит, systemd кладёт в отдельную группу. Поэтому stop завершает их все, а не только главный, а в статусе видно память и процессорное время всей группы. Вывод программы в консоль не теряется, а попадает в журнал, откуда его читает journalctl. Именно поэтому службе не нужен терминал и ей всё равно, подключены вы по SSH или нет.

Два независимых действия, которые часто путают:

Действие Команда Что происходит
запустить start служба работает прямо сейчас, после перезагрузки не поднимется
включить enable будет запускаться при загрузке, но сейчас не стартует
оба сразу enable --now то, что обычно и нужно

И третье: если в юните стоит Restart=always, после падения процесса systemd подождёт заданную паузу и запустит его снова.

1. Статус службы

systemctl status nginx

Важное в первых строках:

  • Loaded — где лежит юнит и после ; состояние автозапуска: enabled или disabled;
  • Active — active (running) работает, inactive (dead) остановлена, failed упала;
  • Main PID — главный процесс.

Если вывод не влезает в экран, откроется просмотрщик, выход — q.

2. Управление

systemctl start nginx      # запустить
systemctl stop nginx       # остановить
systemctl restart nginx    # перезапустить
systemctl reload nginx     # перечитать настройки без остановки, если служба умеет

systemctl enable nginx     # включить автозапуск
systemctl disable nginx    # выключить автозапуск
systemctl enable --now nginx   # включить автозапуск и сразу запустить

Для скриптов удобны короткие проверки:

systemctl is-active nginx
systemctl is-enabled nginx

Что работает и что упало:

systemctl list-units --type=service --state=running
systemctl --failed

3. Логи службы

# Последние 50 строк
journalctl -u nginx -n 50

# В реальном времени, выход по Ctrl+C
journalctl -u nginx -f

# За последний час
journalctl -u nginx --since "1 hour ago"

Подробнее про журнал — в статье логи Linux и journalctl.

4. Своя служба

Допустим, есть Python-скрипт — например, Telegram-бот — и он должен работать всегда. Запущенный в терминале, он умрёт вместе с SSH-сессией. Делаем службу.

Отдельный пользователь без права входа, чтобы бот не получил лишних прав даже при уязвимости в коде:

useradd -r -s /usr/sbin/nologin appuser

Скрипт лежит в /opt/mybot/bot.py, папка принадлежит этому пользователю:

chown -R appuser:appuser /opt/mybot

Файл юнита:

nano /etc/systemd/system/mybot.service
[Unit]
Description=My Telegram bot
After=network-online.target
Wants=network-online.target

[Service]
User=appuser
WorkingDirectory=/opt/mybot
ExecStart=/usr/bin/python3 /opt/mybot/bot.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Сохраните (Ctrl+O, Enter, Ctrl+X), сообщите systemd о новом файле, включите и проверьте:

systemctl daemon-reload
systemctl enable --now mybot
systemctl status mybot

Что означают строки:

  • After и Wants с network-online.target откладывают запуск, пока не поднимется сеть;
  • User — от чьего имени работает скрипт;
  • WorkingDirectory — папка, где скрипт ищет свои файлы;
  • ExecStart — команда запуска с полным путём к интерпретатору; путь узнаётся через which python3;
  • Restart=always и RestartSec=5 — перезапуск через 5 секунд после любого завершения;
  • WantedBy=multi-user.target — автозапуск при загрузке.

Проверить автоперезапуск просто: kill главного процесса, и через пять секунд systemctl status mybot снова покажет active (running).

После каждой правки юнита — systemctl daemon-reload, затем systemctl restart mybot. Без первой команды systemd продолжит пользоваться старой версией файла. Проверка на ошибки: systemd-analyze verify /etc/systemd/system/mybot.service.

Живой пример с виртуальным окружением и токеном в отдельном файле — в статье Telegram-бот как служба systemd.

Частые ошибки

status=203/EXEC. systemd не смог запустить программу из ExecStart. Типичный случай — /usr/bin/python вместо /usr/bin/python3. Проверьте путь через which. Если запускаете скрипт напрямую, у него должно быть право x и первая строка #!/usr/bin/env python3.

Unit mybot.service could not be found. Файл не в /etc/systemd/system/, называется иначе, чем в команде, или не выполнен daemon-reload.

Служба перезапускается по кругу. Программа падает сразу после старта, Restart=always поднимает её снова. Причина в journalctl -u mybot -n 50: ошибка в скрипте, нет библиотеки или нет прав на файлы.

Удалить свою службу

systemctl disable --now mybot
rm /etc/systemd/system/mybot.service
systemctl daemon-reload

Для задач по расписанию, а не постоянной работы, вместо службы нужен cron.