Своя служба systemd — самый надёжный способ настроить автозапуск в Linux для чего угодно: Telegram-бота, Node.js-приложения, парсера, самописного API. Один unit-файл на 10 строк — и ваш процесс стартует вместе с сервером, сам поднимается после падения и пишет логи в одно предсказуемое место. В этой статье разберём структуру unit-файла, параметр Restart=always, управление через systemctl и отладку через journalctl — всё на примерах для Ubuntu 24.04 LTS.
Зачем нужна своя служба systemd, если есть screen и nohup
Новички обычно запускают скрипты через screen, tmux или nohup. Это работает ровно до первой перезагрузки VPS или первого необработанного исключения. Дальше — процесс мёртв, а вы узнаёте об этом от пользователей.
Systemd — это система инициализации, которая управляет всеми процессами в современных дистрибутивах (Ubuntu, Debian, AlmaLinux, Rocky Linux). Оформив программу как службу, вы получаете:
- Автозапуск при загрузке — сервер перезагрузился, служба поднялась сама;
- Автоперезапуск после сбоя — упал процесс, systemd перезапустил его через заданное число секунд;
- Централизованные логи — весь stdout/stderr попадает в journald, не нужно городить перенаправления в файлы;
- Единое управление —
start,stop,restart,statusодними и теми же командами; - Ограничения ресурсов — можно лимитировать память и CPU конкретной службы.
Подробное сравнение способов запуска скриптов мы разбирали в статье про запуск Python-скриптов 24/7 — здесь сосредоточимся именно на systemd.
Анатомия unit-файла: три секции
Unit-файл — это текстовый файл в формате INI. Свои службы кладут в каталог /etc/systemd/system/, имя файла — это имя службы: mybot.service → служба mybot. Минимальный рабочий unit-файл выглядит так:
[Unit]
Description=My Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=botuser
WorkingDirectory=/opt/mybot
ExecStart=/usr/bin/python3 /opt/mybot/bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Что означает каждая секция:
[Unit] — описание и зависимости
Description— человекочитаемое имя, видно вsystemctl status;After=network-online.target— стартовать после того, как поднялась сеть. Для ботов и всего, что ходит в интернет, — обязательно;Wants=— мягкая зависимость: подтянуть указанный target, но не падать, если он недоступен.
[Service] — как запускать процесс
Type=simple— процесс в ExecStart и есть сама служба (подходит для 95% случаев). Для программ, которые сами уходят в фон, используютType=forking;User— от кого запускать. Никогда не запускайте бота от root без необходимости;WorkingDirectory— рабочий каталог. Без него относительные пути в скрипте сломаются;ExecStart— команда запуска. Только абсолютные пути: systemd не знает ваш$PATHиз.bashrc;RestartиRestartSec— политика перезапуска, о ней ниже.
[Install] — когда включать
WantedBy=multi-user.target означает «запускать при обычной загрузке системы». Именно эта строка делает возможным systemctl enable.
Пошагово: служба для своего скрипта за 5 минут
- Проверьте ручной запуск. Программа должна работать от нужного пользователя по абсолютному пути:
sudo -u botuser /usr/bin/python3 /opt/mybot/bot.py. Если тут ошибка — служба её унаследует. - Создайте unit-файл:
sudo nano /etc/systemd/system/mybot.service— и вставьте шаблон выше, поправив пути и пользователя. - Перечитайте конфигурацию:
sudo systemctl daemon-reload
Эту команду нужно повторять после каждого изменения unit-файла.
- Запустите и проверьте:
sudo systemctl start mybot
systemctl status mybot
В статусе должно быть active (running) зелёным.
- Включите автозапуск:
sudo systemctl enable mybot
Теперь после ребута служба поднимется сама. Команда enable --now объединяет включение и запуск.
На VPS от Cheap-Host сервер выдаётся за 45–60 секунд после оплаты, так что весь путь «купил сервер → бот работает как служба» реально пройти минут за десять. Для пары ботов и скриптов достаточно тарифа Start за 450 ₽/мес — 6 vCPU и 8 ГБ RAM с запасом.
Restart=always: служба, которая не умирает
Параметр Restart определяет, что делать, когда процесс завершился. Основные значения:
| Значение | Когда перезапускать | Кому подходит |
|---|---|---|
no | Никогда (по умолчанию) | Разовые задачи |
on-failure | Только при ненулевом коде выхода или сигнале | Скрипты, которые могут штатно завершаться |
always | При любом завершении, даже успешном | Боты, серверы, демоны — всё, что должно жить вечно |
RestartSec=5 задаёт паузу перед перезапуском. Не ставьте 0: если приложение падает мгновенно (например, нет доступа к API), вы получите цикл быстрых рестартов и упрётесь в лимит — по умолчанию systemd разрешает 5 запусков за 10 секунд, после чего переводит службу в состояние failed. Для «упрямого» перезапуска лимит можно ослабить:
[Unit]
StartLimitIntervalSec=60
StartLimitBurst=10
Сбросить счётчик неудач вручную: sudo systemctl reset-failed mybot.
journalctl: где смотреть логи службы
Всё, что служба пишет в stdout и stderr, попадает в журнал systemd. Основные команды:
# Последние 50 строк службы
journalctl -u mybot -n 50
# Следить за логом в реальном времени (аналог tail -f)
journalctl -u mybot -f
# Логи за сегодня
journalctl -u mybot --since today
# Только ошибки и хуже
journalctl -u mybot -p err
Пара практических советов. Во-первых, для Python добавьте в unit-файл Environment=PYTHONUNBUFFERED=1, иначе вывод будет появляться в журнале с задержкой из-за буферизации. Во-вторых, проверьте, что журнал персистентный: если каталога /var/log/journal нет, логи живут в памяти и пропадают при ребуте. Лечится так:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
Именно связка systemctl status + journalctl -u закрывает 90% вопросов «почему не работает». Это сильно удобнее, чем искать разбросанные по диску лог-файлы, — тот же подход выручает и при самостоятельном мониторинге VPS.
Полезные параметры для реальных задач
Несколько строк, которые стоит знать помимо базового шаблона:
Environment=TOKEN=abc123— переменные окружения прямо в unit-файле;EnvironmentFile=/opt/mybot/.env— то же, но из файла (удобно для секретов, не забудьтеchmod 600);ExecStartPre=— команда перед запуском, например миграции базы;MemoryMax=512M— жёсткий потолок памяти: служба не съест весь VPS;CPUQuota=50%— ограничение процессора;NoNewPrivileges=trueиProtectSystem=full— базовое «песочничание» процесса.
Таким же способом оформляют автозапуск чего угодно: Node.js-приложений (хотя там популярен и PM2 — сравнение есть в статье про деплой Node.js на VPS), Go-бинарников, Java-серверов, самописных прокси. А для задач по расписанию у systemd есть таймеры — более гибкая альтернатива классическому cron: они умеют догонять пропущенные запуски через Persistent=true и наследуют все возможности служб.
Частые ошибки новичков
- Забыли
daemon-reloadпосле правки unit-файла — systemd работает со старой версией; - Относительные пути в ExecStart — служба не находит интерпретатор или скрипт;
- Рассчитывали на .bashrc — виртуальные окружения Python активируйте явно:
ExecStart=/opt/mybot/venv/bin/python /opt/mybot/bot.py; - Сделали
start, но неenable— после перезагрузки служба не поднялась; - Запуск от root без причины — при взломе приложения атакующий получает весь сервер.
FAQ
Чем systemd-служба лучше запуска через screen или nohup?
Служба переживает перезагрузку, сама перезапускается после падения, пишет логи в journald и управляется стандартным systemctl. Screen и nohup после ребута оставляют вас с мёртвым процессом.
Почему служба не стартует, хотя скрипт вручную работает?
Почти всегда — пути или окружение: systemd не читает ваш .bashrc. Проверьте абсолютные пути в ExecStart, задайте WorkingDirectory и переменные через Environment=. Причину покажет journalctl -u имя -n 50.
Что делать, если служба падает и перезапускается по кругу?
Смотрите причину в journalctl и чините её. После срабатывания лимита запусков выполните systemctl reset-failed. Для нестабильных приложений увеличьте RestartSec и ослабьте StartLimitBurst.
Можно ли запускать службу не от root?
Нужно: добавьте User= и Group= в секцию [Service]. Приложению почти никогда не нужны права root, а безопасность выигрывает заметно.
Какой сервер нужен, чтобы держать свои службы 24/7?
Systemd сам по себе ресурсов не требует — считайте аппетиты ваших приложений. Несколько ботов и скриптов спокойно живут на VPS Start у Cheap-Host: 6 vCPU, 8 ГБ RAM, NVMe за 450 ₽/мес.
Вывод
Unit-файл из десяти строк превращает любой скрипт в полноценный сервис: автозапуск при загрузке, Restart=always на случай падений и понятные логи в journalctl. Один раз разобравшись с шаблоном, вы будете оформлять так каждый процесс, который должен работать без присмотра. Если для этих задач нужен сервер — у Cheap-Host тариф Start от 450 ₽/мес: KVM с полным root, NVMe-диски, безлимитный трафик и выдача сервера за минуту. Тарифы — на cheap-host.onl.