Как запустить Telegram-бота на Python на облачном сервере VDS/VPS круглосуточно: виртуальное окружение, aiogram 3, токен в защищённом файле, служба systemd с автоперезапуском и журнал.
Содержание
Бот, запущенный на домашнем компьютере, перестаёт отвечать, как только компьютер выключается. На облачном сервере он работает круглосуточно, а служба systemd запускает его при загрузке сервера и перезапускает после сбоя. В статье описан весь путь от получения токена до обновления кода на примере бота на Python с библиотекой aiogram 3.
Команды приведены для Ubuntu 26.04 и 24.04 и Debian 13. Вход на наши серверы выполняется под учётной записью root (подробнее — в статье Как подключиться к серверу по SSH), поэтому sudo в командах не указан.
Получение токена
Откройте в Telegram бота @BotFather, отправьте ему команду /newbot и укажите название и имя пользователя нового бота; имя пользователя должно оканчиваться на «bot». В ответ BotFather пришлёт токен — строку вида 123456789:ABCdefGhIJKlmNoPQRstuVWXyz.
Токен даёт полный доступ к боту, поэтому не публикуйте его и не записывайте в код. Если токен стал известен посторонним, получите новый командой /token в @BotFather и замените его на сервере.
Пользователь и виртуальное окружение Python
Бот будет работать от имени отдельной системной учётной записи без права входа: даже ошибка в коде не даст ему прав администратора. Код и библиотеки бота будут храниться в папке /opt/tgbot.
apt update
apt install python3-venv
useradd --system --shell /usr/sbin/nologin tgbot
mkdir /opt/tgbot
python3 -m venv /opt/tgbot/venv
/opt/tgbot/venv/bin/pip install aiogramВиртуальное окружение (venv) хранит библиотеки бота отдельно от системных: обновление системы их не затрагивает, а установка пакетов через pip не мешает apt. Для aiogram 3 нужен Python 3.10 или новее, и это условие выполняется во всех трёх системах: Ubuntu 26.04 поставляется с Python 3.14, Ubuntu 24.04 — с версией 3.12, Debian 13 — с версией 3.13.
В AlmaLinux 10 пакет python3-venv не нужен: модуль venv входит в состав Python 3.12. В AlmaLinux 9 системный Python 3.9 для aiogram 3 не подходит, поэтому установите Python 3.12 (dnf install python3.12) и создайте окружение с ним: python3.12 -m venv /opt/tgbot/venv.
Код бота
Создайте файл /opt/tgbot/bot.py с минимальным ботом. На команду /start он отвечает приветствием, а на остальные текстовые сообщения — их повтором:
import asyncio
import logging
import os
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart
from aiogram.types import Message
dp = Dispatcher()
@dp.message(CommandStart())
async def start(message: Message) -> None:
await message.answer("Здравствуйте! Бот работает на облачном сервере.")
@dp.message(F.text)
async def echo(message: Message) -> None:
await message.answer(message.text)
async def main() -> None:
bot = Bot(token=os.environ["BOT_TOKEN"])
await dp.start_polling(bot)
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
asyncio.run(main())Токен бот получает из переменной окружения BOT_TOKEN, а не из файла с кодом. Благодаря этому код можно хранить в репозитории и показывать другим, не раскрывая токен.
Токен в файле окружения
Создайте файл для токена и сразу закройте его от других пользователей:
touch /etc/tgbot.env
chmod 600 /etc/tgbot.envОткройте файл в текстовом редакторе и запишите в него одну строку, заменив пример своим токеном:
BOT_TOKEN=123456789:ABCdefGhIJKlmNoPQRstuVWXyzС правами 600 файл может прочитать только root. Боту это не мешает: systemd читает файл до запуска программы и передаёт ей токен в переменной окружения.
Служба systemd с автоперезапуском
Создайте файл /etc/systemd/system/tgbot.service:
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=tgbot
WorkingDirectory=/opt/tgbot
EnvironmentFile=/etc/tgbot.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/tgbot/venv/bin/python /opt/tgbot/bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetRestart=alwaysиRestartSec=5: если бот завершится по любой причине, systemd запустит его снова через пять секунд.User=tgbot: бот работает от имени созданной ранее учётной записи без прав администратора.PYTHONUNBUFFERED=1: то, что программа выводит функцией print(), сразу попадает в журнал, а не задерживается в буфере.- Если боту нужно сохранять данные, например базу SQLite, добавьте в раздел
[Service]строкуStateDirectory=tgbot. systemd создаст папку/var/lib/tgbot, в которую бот сможет записывать файлы.
Запустите службу и включите её автозапуск:
systemctl daemon-reload
systemctl enable --now tgbot
systemctl status tgbotЕсли в выводе последней команды указано active (running), напишите боту в Telegram: он должен ответить. Подробнее о файлах служб рассказано в статье о службах systemd.
Журнал бота
Всё, что выводит бот, в том числе сообщения aiogram об ошибках, записывается в системный журнал. Следить за ним в реальном времени позволяет команда ниже; чтобы выйти из просмотра, нажмите Ctrl+C.
journalctl -u tgbot -fПоследние 100 строк покажет команда journalctl -u tgbot -n 100, записи за последний час — journalctl -u tgbot --since "1 hour ago". Другие приёмы описаны в статье о журнале journalctl. Если бот не отвечает, ищите в журнале такие сообщения:
- Unauthorized означает неверный токен. Проверьте строку в
/etc/tgbot.envи перезапустите службу. - Conflict: terminated by other getUpdates request появляется, когда бот с тем же токеном запущен где-то ещё, например на вашем компьютере. Получать сообщения может только одна копия бота, поэтому остановите лишнюю.
Обновление кода
Чтобы выложить новую версию бота, скопируйте файлы на сервер со своего компьютера:
scp bot.py root@203.0.113.10:/opt/tgbot/Затем перезапустите службу на сервере:
systemctl restart tgbotЕсли бот использует другие библиотеки, перечислите их в файле requirements.txt и после копирования установите командой /opt/tgbot/venv/bin/pip install -r /opt/tgbot/requirements.txt. Для обновления самой aiogram выполните /opt/tgbot/venv/bin/pip install --upgrade aiogram; после обновления библиотек тоже перезапустите службу. Если вы перейдёте на выпуск системы с другой версией Python, создайте виртуальное окружение заново и снова установите в него библиотеки.
Длинный опрос (long polling) или вебхук
Бот из примера получает сообщения методом длинного опроса (long polling): он сам обращается к серверам Telegram и ждёт новых сообщений. Входящие подключения при этом не используются, поэтому боту не нужны ни домен, ни сертификат, ни открытые порты.
При работе через вебхук (webhook) Telegram сам отправляет каждое сообщение на адрес бота по HTTPS. Для этого нужен адрес с сертификатом, обычно домен, и веб-сервер на одном из портов 443, 80, 88 или 8443. Вебхук имеет смысл при большом потоке сообщений или когда на сервере уже работает сайт с HTTPS; большинству ботов достаточно длинного опроса.
Совмещать оба способа нельзя: пока у бота установлен вебхук, длинный опрос не получает сообщений. Чтобы вернуться к длинному опросу, вебхук удаляют методом deleteWebhook.
Не нашли ответ? Напишите в поддержку — подскажем.


