Unit for tg bot
Запуск Python-скрипта как службы systemd
В Linux Python-скрипт можно запустить как системную службу с помощью ‘’‘systemd’’’ .
Это удобно для Telegram-ботов, веб-сервисов и других приложений, которые должны:
- автоматически запускаться вместе с сервером;
- работать в фоновом режиме;
- автоматически перезапускаться после ошибки;
- управляться стандартными командами systemctl;
- сохранять журнал работы в journalctl.
В этой статье рассмотрим два варианта запуска Python-приложения на примере Telegram-бота ‘’‘noProdaction’’’.
TOC
Способ №1 — запуск через отдельный shell-скрипт
В этом варианте systemd запускает вспомогательный shell-скрипт, который, в свою очередь, запускает Python-приложение.
Схема запуска:
systemd │ ▼ noProdaction.sh │ ▼ python3 │ ▼ main.py
Создание скрипта запуска
Создаём каталог для скрипта запуска, если его ещё нет:
mkdir -p /opt/Python/Telegram/start
Создаём файл:
nano /opt/Python/Telegram/start/noProdaction.sh
Добавляем:
#!/bin/bash
exec /usr/bin/python3.11 /opt/Python/Telegram/noProdaction/noprodaction-1/main.py
Сохраняем файл:
<pre>
Ctrl + O
Enter
Ctrl + X
</pre>
Делаем его исполняемым:
<syntaxhighlight lang="bash">
chmod +x /opt/Python/Telegram/start/noProdaction.sh
Создание systemd unit
Создаём unit-файл:
nano /etc/systemd/system/noprodaction.service
Добавляем:
[Unit]
Description=Telegram bot noProdaction
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/Python/Telegram/noProdaction/noprodaction-1
ExecStart=/opt/Python/Telegram/start/noProdaction.sh
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateDevices=true
ProtectSystem=full
[Install]
WantedBy=multi-user.target
Сохраняем файл:
<pre>
Ctrl + O
Enter
Ctrl + X
</pre>
=== Активация службы ===
После создания или изменения unit-файла необходимо перечитать конфигурацию systemd:
<syntaxhighlight lang="bash">
systemctl daemon-reload
Добавляем службу в автозагрузку:
systemctl enable noprodaction.service
Запускаем:
systemctl start noprodaction.service
Можно выполнить обе команды сразу:
systemctl enable --now noprodaction.service
Проверка работы
Проверяем состояние:
systemctl status noprodaction.service
При нормальной работе должна присутствовать строка:
Active: active (running)
Например:
● noprodaction.service - Telegram bot noProdaction
Loaded: loaded (/etc/systemd/system/noprodaction.service; enabled)
Active: active (running)
Main PID: 173 (python3.11)
Tasks: 2
Memory: 34.1M
CPU: 1.766s
Способ №2 — запуск Python напрямую из systemd
Схема становится проще:
systemd │ ▼ python3 │ ▼ main.py
Создаём unit-файл:
nano /etc/systemd/system/noprodaction.service
Добавляем:
[Unit]
Description=Telegram bot noProdaction
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/Python/Telegram/noProdaction/noprodaction-1
ExecStart=/usr/bin/python3.11 /opt/Python/Telegram/noProdaction/noprodaction-1/main.py
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateDevices=true
ProtectSystem=full
[Install]
WantedBy=multi-user.target
После создания файла выполняем:
<syntaxhighlight lang="bash">
systemctl daemon-reload
systemctl enable --now noprodaction.service
Проверяем:
systemctl status noprodaction.service
Управление службой
После создания unit-файла ботом можно управлять стандартными командами systemd.
| Действие | Команда
Проверить состояние systemctl status noprodaction - Запустить systemctl start noprodaction - Остановить systemctl stop noprodaction - Перезапустить systemctl restart noprodaction - Добавить в автозагрузку systemctl enable noprodaction - Убрать из автозагрузки systemctl disable noprodaction } Просмотр логовОдно из преимуществ запуска через systemd — вывод Python-приложения автоматически попадает в системный журнал. Посмотреть последние записи: journalctl -u noprodaction.service
Последние 100 строк: journalctl -u noprodaction.service -n 100
Следить за журналом в реальном времени: journalctl -u noprodaction.service -f
Выйти из режима просмотра: Ctrl + C Посмотреть журнал только с момента последней загрузки сервера: journalctl -u noprodaction.service -b
После изменения Python-кодаЕсли был изменён только код main.py или других файлов приложения, выполнять daemon-reload не требуется. Достаточно перезапустить приложение: systemctl restart noprodaction
Если же был изменён сам файл: /etc/systemd/system/noprodaction.service необходимо выполнить: systemctl daemon-reload
systemctl restart noprodaction
Автоматический перезапускВ нашем unit-файле используются параметры: Restart=on-failure
RestartSec=5
Это означает, что если Python-процесс аварийно завершится, systemd подождёт 5 секунд и попробует запустить его снова. Проверить количество перезапусков можно командой: systemctl show noprodaction.service -p NRestarts
Проверка пути к PythonПуть к Python может отличаться в зависимости от системы. Проверить его можно командой: which python3
Например: /usr/bin/python3 Версию Python: python3 --version
Если конкретная версия Python не требуется, в unit-файле можно использовать: ExecStart=/usr/bin/python3 /opt/Python/Telegram/noProdaction/noprodaction-1/main.py
Запуск через Python Virtual EnvironmentЕсли проект использует собственное виртуальное окружение Python, рекомендуется запускать Python непосредственно из него. Например, если виртуальное окружение находится здесь: /opt/Python/Telegram/noProdaction/venv/ то ExecStart будет выглядеть так: ExecStart=/opt/Python/Telegram/noProdaction/venv/bin/python /opt/Python/Telegram/noProdaction/noprodaction-1/main.py
Активировать venv командой source внутри systemd не требуется. Рекомендуемый unit-файлДля обычного Python-приложения итоговый вариант может выглядеть следующим образом: [Unit]
Description=Telegram bot noProdaction
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/Python/Telegram/noProdaction/noprodaction-1
ExecStart=/usr/bin/python3.11 /opt/Python/Telegram/noProdaction/noprodaction-1/main.py
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateDevices=true
ProtectSystem=full
[Install]
WantedBy=multi-user.target
После создания:
<syntaxhighlight lang="bash">
systemctl daemon-reload
systemctl enable --now noprodaction.service
Проверяем: systemctl status noprodaction.service
и журнал: journalctl -u noprodaction.service -f
Примечание по безопасностиВ примерах выше служба запускается от пользователя: User=root
Для собственного сервера это работает, однако большинству Python-приложений права root не нужны. Более безопасный вариант — создать отдельного системного пользователя для приложения и запускать службу от его имени. Например: useradd --system --home /opt/Python/Telegram/noProdaction --shell /usr/sbin/nologin noprodaction
После этого необходимо выдать пользователю права на необходимые файлы приложения и заменить в unit-файле: User=root
на: User=noprodaction
ИтогДля простого Python-приложения рекомендуется использовать ‘’‘Способ №2’’’: Загрузка Linux
│
▼
systemd
│
▼
noprodaction.service
│
▼
Python
│
▼
main.py
│
▼
Telegram Bot
После этого приложение автоматически запускается вместе с системой, работает в фоне и при аварийном завершении автоматически запускается снова. |
|---|