Многие, впервые разместив Python-бота на сервере, запускают его по SSH командой python3 bot.py и радуются, что всё работает. Но стоит закрыть окно терминала или потерять SSH-соединение, как бот останавливается. Затем в ход идут nohup или screen, однако после перезагрузки сервера или падения бота с ошибкой его никто не поднимет. Чтобы бот действительно работал круглосуточно, его нужно превратить в службу, которой управляет операционная система.
Почему обычный хостинг для этого не подходит
Обычный виртуальный хостинг рассчитан прежде всего на PHP-сайты: пришёл запрос, скрипт отработал и завершился. Постоянно работающие процессы в такой среде, как правило, останавливаются ограничениями ресурсов или самой системой, а попытки «держать бота живым» через cron надёжного результата не дают. Поэтому для бота, который должен работать 24/7, правильный выбор — VPS с root-доступом. На VPS вы сами создаёте службу systemd, и бот стартует вместе с системой.
Подготовка: отдельный пользователь и виртуальное окружение
Запускать бота от имени root — плохая привычка с точки зрения безопасности. Лучше создать для бота отдельного системного пользователя и разместить код в его каталоге. Библиотеки ставьте не в системный Python, а в виртуальное окружение, тогда не возникнет конфликтов версий с другими проектами.
sudo adduser --system --group --home /opt/mybot mybot
sudo -u mybot python3 -m venv /opt/mybot/venv
sudo -u mybot /opt/mybot/venv/bin/pip install -r /opt/mybot/requirements.txt
Не записывайте токен бота и другие секреты прямо в код. Храните их в отдельном файле .env и дайте право чтения только пользователю бота. Это заодно защитит от случайной публикации токена на GitHub.
sudo nano /opt/mybot/.env
# BOT_TOKEN=123456:ABC...
sudo chown mybot:mybot /opt/mybot/.env
sudo chmod 600 /opt/mybot/.env
Создание службы systemd
systemd — основной менеджер служб в современных дистрибутивах Linux. Он запускает процесс, поднимает его после падения, включает при загрузке сервера и пишет весь вывод в журнал. Для этого достаточно одного unit-файла.
sudo nano /etc/systemd/system/mybot.service
[Unit]
Description=Telegram bot (mybot)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/opt/mybot/.env
ExecStart=/opt/mybot/venv/bin/python -u bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Параметр Restart=always перезапустит бота через пять секунд, по какой бы причине он ни остановился. Флаг -u отключает буферизацию вывода Python, поэтому сообщения сразу появляются в журнале. Когда файл готов, сообщите systemd о новой службе и включите её.
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
systemctl status mybot
Просмотр логов
Отдельный лог-файл заводить не обязательно: systemd собирает весь вывод в журнал. Команды ниже показывают последние записи или следят за новыми в реальном времени. После обновления кода службу перезапускают одной командой.
journalctl -u mybot -n 100
journalctl -u mybot -f
sudo systemctl restart mybot
Вариант с PM2
PM2 создавался как менеджер процессов для Node.js, но и с Python-скриптами справляется без проблем. Если на сервере уже работают Node.js-проекты под PM2, удобно видеть все процессы в одном списке. Для установки PM2 на сервере должны быть Node.js и npm.
sudo npm install -g pm2
cd /opt/mybot
pm2 start bot.py --name mybot --interpreter /opt/mybot/venv/bin/python
pm2 save
pm2 startup
Команда pm2 startup выводит на экран строку с sudo, которую нужно скопировать и выполнить, иначе после перезагрузки PM2 не запустится сам. pm2 save сохраняет текущий список процессов. Дальше логи смотрят через pm2 logs mybot, а перезапуск делают командой pm2 restart mybot.
systemd или PM2: что выбрать
| Критерий | systemd | PM2 |
|---|---|---|
| Дополнительная установка | Не нужна, уже есть в системе | Нужны Node.js и npm |
| Логи | journalctl | pm2 logs, ~/.pm2/logs |
| Обзор нескольких процессов | systemctl list-units | pm2 list, pm2 monit |
| Кому удобнее | Чисто Python-проекты | Смешанные серверы с Node.js |
Если у вас один-два Python-бота, systemd — самый простой и надёжный путь без лишних зависимостей. PM2 удобен тем, кто хочет следить за множеством проектов из одной панели.
Практический пример: бот цветочного магазина в Ташкенте
Представим, что цветочный магазин в Ташкенте принимает заказы через Telegram-бота и записывает каждый заказ в базу сайта misol.uz. Раньше бот работал на ноутбуке разработчика, и ночью, когда ноутбук закрывали, заказы терялись. После переноса на небольшой VPS и запуска через описанную службу systemd бот стартует вместе с сервером, а при сетевом сбое поднимается за пять секунд. Владелец магазина при проблеме смотрит точный текст ошибки через journalctl -u mybot и пересылает его разработчику.
Частые ошибки
- Относительные пути в unit-файле: в
ExecStartвсегда указывайте полный путь. - Системный Python вместо виртуального окружения — в итоге ошибка «модуль не найден».
- Одновременный запуск одного бота и через systemd, и через PM2: Telegram выдаст ошибку о конфликте запросов двух экземпляров.
- Забытый
daemon-reloadпосле изменения файла службы.
Если боту нужен сервер, VPS можно заказать в кабинете sayt.uz и выполнить описанную настройку за несколько минут. Главное, чтобы бот был привязан не к терминалу, а к системе.