Unit for tg bot: различия между версиями
Artem (обсуждение | вклад) Нет описания правки Метки: с мобильного устройства из мобильной версии |
Artem (обсуждение | вклад) Нет описания правки Метки: с мобильного устройства из мобильной версии |
||
| (не показаны 2 промежуточные версии этого же участника) | |||
| Строка 1: | Строка 1: | ||
= | = Запуск Python-скрипта как службы systemd = | ||
В Linux Python-скрипт можно запустить как системную службу с помощью ‘’‘systemd’’’ . | |||
Это удобно для Telegram-ботов, веб-сервисов и других приложений, которые должны: | |||
* автоматически запускаться вместе с сервером; | |||
* работать в фоновом режиме; | |||
* автоматически перезапускаться после ошибки; | |||
* управляться стандартными командами systemctl; | |||
* сохранять журнал работы в journalctl. | |||
В этой статье рассмотрим два варианта запуска Python-приложения на примере Telegram-бота ‘’‘noProdaction’’’. | |||
TOC | |||
== Способ №1 — запуск через отдельный shell-скрипт == | |||
В этом варианте systemd запускает вспомогательный shell-скрипт, который, в свою очередь, запускает Python-приложение. | |||
Схема запуска: | |||
<pre> | |||
systemd | |||
│ | |||
▼ | |||
noProdaction.sh | |||
│ | |||
▼ | |||
python3 | |||
│ | |||
▼ | |||
main.py | |||
</pre> | |||
=== Создание скрипта запуска === | |||
Создаём каталог для скрипта запуска, если его ещё нет: | |||
<syntaxhighlight lang="bash"> | |||
mkdir -p /opt/Python/Telegram/start | |||
</syntaxhighlight> | |||
Создаём файл: | |||
<syntaxhighlight lang="bash"> | |||
nano /opt/Python/Telegram/start/noProdaction.sh | |||
</syntaxhighlight> | |||
Добавляем: | |||
и | <syntaxhighlight lang="bash"> | ||
#!/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 | |||
</syntaxhighlight> | |||
{{Note|Использование exec позволяет заменить процесс shell непосредственно процессом Python. Благодаря этому systemd корректнее отслеживает PID приложения и управляет его завершением.}} | |||
=== Создание systemd unit === | |||
Создаём unit-файл: | |||
<syntaxhighlight lang="bash"> | |||
nano /etc/systemd/system/noprodaction.service | |||
</syntaxhighlight> | |||
Добавляем: | |||
<syntaxhighlight lang="ini"> | |||
[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 | |||
</syntaxhighlight> | |||
Добавляем службу в автозагрузку: | |||
<syntaxhighlight lang="bash"> | |||
systemctl enable noprodaction.service | |||
</syntaxhighlight> | |||
Запускаем: | |||
<syntaxhighlight lang="bash"> | |||
systemctl start noprodaction.service | |||
</syntaxhighlight> | |||
Можно выполнить обе команды сразу: | |||
<syntaxhighlight lang="bash"> | |||
systemctl enable --now noprodaction.service | |||
</syntaxhighlight> | |||
=== Проверка работы === | |||
Проверяем состояние: | |||
<syntaxhighlight lang="bash"> | |||
systemctl status noprodaction.service | |||
</syntaxhighlight> | |||
При нормальной работе должна присутствовать строка: | |||
<pre> | |||
Active: active (running) | |||
</pre> | |||
Например: | |||
<pre> | |||
● 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 | |||
</pre> | |||
== Способ №2 — запуск Python напрямую из systemd == | |||
{{Note|’’‘Рекомендуемый вариант.’’’ Если для запуска приложения не требуется выполнять дополнительные команды, создавать отдельный .sh-файл нет необходимости. Python можно запускать непосредственно из systemd.}} | |||
Схема становится проще: | |||
<pre> | |||
systemd | |||
│ | |||
▼ | |||
python3 | |||
│ | |||
▼ | |||
main.py | |||
</pre> | |||
Создаём unit-файл: | |||
<syntaxhighlight lang="bash"> | |||
nano /etc/systemd/system/noprodaction.service | |||
</syntaxhighlight> | |||
Добавляем: | |||
<syntaxhighlight lang="ini"> | |||
[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 | |||
</syntaxhighlight> | |||
Проверяем: | |||
<syntaxhighlight lang="bash"> | |||
systemctl status noprodaction.service | |||
</syntaxhighlight> | |||
== Управление службой == | |||
После создания unit-файла ботом можно управлять стандартными командами systemd. | |||
{| class=“wikitable” | |||
! Действие | |||
! Команда | |||
Проверить состояние | |||
systemctl status noprodaction | |||
- | |||
Запустить | |||
systemctl start noprodaction | |||
- | |||
Остановить | |||
systemctl stop noprodaction | |||
- | |||
Перезапустить | |||
systemctl restart noprodaction | |||
- | |||
Добавить в автозагрузку | |||
systemctl enable noprodaction | |||
- | |||
Убрать из автозагрузки | |||
systemctl disable noprodaction | |||
} | |||
== Просмотр логов == | |||
Одно из преимуществ запуска через systemd — вывод Python-приложения автоматически попадает в системный журнал. | |||
Посмотреть последние записи: | |||
<syntaxhighlight lang="bash"> | |||
journalctl -u noprodaction.service | |||
</syntaxhighlight> | |||
Последние 100 строк: | |||
<syntaxhighlight lang="bash"> | |||
journalctl -u noprodaction.service -n 100 | |||
</syntaxhighlight> | |||
Следить за журналом в реальном времени: | |||
<syntaxhighlight lang="bash"> | |||
journalctl -u noprodaction.service -f | |||
</syntaxhighlight> | |||
Выйти из режима просмотра: | |||
<pre> | |||
Ctrl + C | |||
</pre> | |||
Посмотреть журнал только с момента последней загрузки сервера: | |||
<syntaxhighlight lang="bash"> | |||
journalctl -u noprodaction.service -b | |||
</syntaxhighlight> | |||
== После изменения Python-кода == | |||
Если был изменён только код main.py или других файлов приложения, выполнять daemon-reload не требуется. | |||
Достаточно перезапустить приложение: | |||
<syntaxhighlight lang="bash"> | |||
systemctl restart noprodaction | |||
</syntaxhighlight> | |||
Если же был изменён сам файл: | |||
<pre> | |||
/etc/systemd/system/noprodaction.service | |||
</pre> | |||
необходимо выполнить: | |||
<syntaxhighlight lang="bash"> | |||
systemctl daemon-reload | |||
systemctl restart noprodaction | |||
</syntaxhighlight> | |||
== Автоматический перезапуск == | |||
В нашем unit-файле используются параметры: | |||
<syntaxhighlight lang="ini"> | |||
Restart=on-failure | |||
RestartSec=5 | |||
</syntaxhighlight> | |||
Это означает, что если Python-процесс аварийно завершится, systemd подождёт 5 секунд и попробует запустить его снова. | |||
Проверить количество перезапусков можно командой: | |||
<syntaxhighlight lang="bash"> | |||
systemctl show noprodaction.service -p NRestarts | |||
</syntaxhighlight> | |||
== Проверка пути к Python == | |||
Путь к Python может отличаться в зависимости от системы. | |||
Проверить его можно командой: | |||
<syntaxhighlight lang="bash"> | |||
which python3 | |||
</syntaxhighlight> | |||
Например: | |||
<pre> | |||
/usr/bin/python3 | |||
</pre> | |||
Версию Python: | |||
<syntaxhighlight lang="bash"> | |||
python3 --version | |||
</syntaxhighlight> | |||
Если конкретная версия Python не требуется, в unit-файле можно использовать: | |||
<syntaxhighlight lang="ini"> | |||
ExecStart=/usr/bin/python3 /opt/Python/Telegram/noProdaction/noprodaction-1/main.py | |||
</syntaxhighlight> | |||
== Запуск через Python Virtual Environment == | |||
Если проект использует собственное виртуальное окружение Python, рекомендуется запускать Python непосредственно из него. | |||
Например, если виртуальное окружение находится здесь: | |||
<pre> | |||
/opt/Python/Telegram/noProdaction/venv/ | |||
</pre> | |||
то ExecStart будет выглядеть так: | |||
<syntaxhighlight lang="ini"> | |||
ExecStart=/opt/Python/Telegram/noProdaction/venv/bin/python /opt/Python/Telegram/noProdaction/noprodaction-1/main.py | |||
</syntaxhighlight> | |||
Активировать venv командой source внутри systemd не требуется. | |||
== Рекомендуемый unit-файл == | |||
Для обычного Python-приложения итоговый вариант может выглядеть следующим образом: | |||
<syntaxhighlight lang="ini"> | |||
[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 | |||
</syntaxhighlight> | |||
Проверяем: | |||
<syntaxhighlight lang="bash"> | |||
systemctl status noprodaction.service | |||
</syntaxhighlight> | |||
и журнал: | |||
<syntaxhighlight lang="bash"> | |||
journalctl -u noprodaction.service -f | |||
</syntaxhighlight> | |||
== Примечание по безопасности == | |||
В примерах выше служба запускается от пользователя: | |||
<syntaxhighlight lang="ini"> | |||
User=root | |||
</syntaxhighlight> | |||
Для собственного сервера это работает, однако большинству Python-приложений права root не нужны. | |||
Более безопасный вариант — создать отдельного системного пользователя для приложения и запускать службу от его имени. | |||
Например: | |||
<syntaxhighlight lang="bash"> | |||
useradd --system --home /opt/Python/Telegram/noProdaction --shell /usr/sbin/nologin noprodaction | |||
</syntaxhighlight> | |||
После этого необходимо выдать пользователю права на необходимые файлы приложения и заменить в unit-файле: | |||
<syntaxhighlight lang="ini"> | |||
User=root | |||
</syntaxhighlight> | |||
на: | |||
<syntaxhighlight lang="ini"> | |||
User=noprodaction | |||
</syntaxhighlight> | |||
{{Warning|Не храните токены Telegram-бота, API-ключи, пароли баз данных и другие секреты непосредственно в публичном unit-файле или исходном коде проекта. Для секретов лучше использовать отдельный файл окружения с ограниченными правами доступа.}} | |||
== Итог == | |||
Для простого Python-приложения рекомендуется использовать ‘’‘Способ №2’’’: | |||
<pre> | |||
Загрузка Linux | |||
│ | |||
▼ | |||
systemd | |||
│ | |||
▼ | |||
noprodaction.service | |||
│ | |||
▼ | |||
Python | |||
│ | |||
▼ | |||
main.py | |||
│ | |||
▼ | |||
Telegram Bot | |||
</pre> | |||
После этого приложение автоматически запускается вместе с системой, работает в фоне и при аварийном завершении автоматически запускается снова. | |||
Текущая версия от 21:36, 31 августа 2026
Запуск 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
После этого приложение автоматически запускается вместе с системой, работает в фоне и при аварийном завершении автоматически запускается снова. |
|---|