Пока бот работает на домашнем компьютере, он отвечает, только когда компьютер включён. На VPS бот работает круглосуточно, переживает перезагрузки и не зависит от вашего интернета. В этой статье мы создадим бота в Telegram, запустим его на сервере на Python с библиотекой aiogram, настроим автозапуск через systemd и разберём ошибки, которые встречаются чаще всего. В качестве примера возьмём простого бота, который здоровается и повторяет сообщения, а свой код вы потом подставите на его место. Все шаги мы проверили на тестовом сервере с Debian 12, Python 3.11 и aiogram 3.31.
Как бот получает сообщения
Бот в Telegram – это обычная программа, которая общается с серверами Telegram через Bot API. Пользователь пишет боту, сообщение попадает на серверы Telegram и ждёт там, пока программа бота его заберёт. По документации Telegram, есть два способа получать такие сообщения, и одновременно можно использовать только один. Первый способ называется polling. Бот сам постоянно спрашивает у Telegram, нет ли новых сообщений. Второй способ, webhook, работает наоборот. Telegram сам отправляет каждое сообщение на адрес вашего сервера, и для этого нужен домен с HTTPS.
Для бота на VPS проще всего polling. Ему не нужны домен, сертификат и открытые порты, ведь соединение всегда начинает сам бот. На нашем тестовом сервере был включён брандмауэр UFW без единого правила для бота, и бот работал. Сообщения, которые пришли, пока бот был выключен, Telegram хранит до 24 часов, так что после короткого перезапуска бот их получит.
Доступ к боту даёт токен, длинная строка, которую выдаёт BotFather. Кто знает токен, тот полностью управляет ботом. Поэтому токен не пишут прямо в код и не выкладывают вместе с ним на GitHub, а хранят в отдельном файле, который может прочитать только root.
Что понадобится
- Сервер с Debian 12 или Ubuntu 24.04. Простому боту хватит самого маленького тарифа, например DE-Promo. Если сервера ещё нет, закажите его по инструкции.
- Подключение по SSH, например через Termius. Команды выполняются от имени
root. - Аккаунт в Telegram, чтобы создать бота.
Шаг 1. Создайте бота в BotFather
- Откройте в Telegram бота @BotFather и отправьте ему команду
/newbot. - Введите имя бота. Его увидят пользователи, имя может быть любым.
- Введите адрес бота. Он должен заканчиваться на
bot, напримерmy_shop_bot. - BotFather пришлёт ссылку на бота и токен под строкой Use this token to access the HTTP API. Скопируйте токен и никому его не показывайте.

Бот создан, токен скрыт
Если токен попал в чужие руки
Отзовите его командой /revoke в BotFather, а затем замените токен на сервере в файле /etc/tgbot.env и перезапустите бота.
Шаг 2. Подготовьте сервер
Создайте для бота отдельного пользователя. Если в коде бота найдётся ошибка, через которую можно выполнить чужие команды, злоумышленник получит права только этого пользователя, а не root.
useradd -r -m -d /opt/tgbot -s /bin/bash tgbot
apt install -y python3-venvПакет python3-venv нужен для виртуального окружения, отдельной папки с библиотеками только для этого бота. В нашем образе Debian 12 его по умолчанию нет.
Перейдите в пользователя бота, создайте окружение и установите aiogram.
su - tgbot
python3 -m venv venv
venv/bin/pip install aiogramВ конце установки появится строка Successfully installed со списком пакетов, среди них aiogram.
Шаг 3. Напишите код бота
Создайте файл с кодом.
nano bot.pyВставьте в него пример ниже и сохраните сочетанием Ctrl + O, затем Enter, а выйдите сочетанием Ctrl + X.
import asyncio
import logging
import os
from aiogram import Bot, Dispatcher
from aiogram.filters import CommandStart
from aiogram.types import Message
dp = Dispatcher()
@dp.message(CommandStart())
async def start(message: Message):
# ответ на команду /start
await message.answer(f"Привет, {message.from_user.first_name}! Я работаю на VPS. Напишите что-нибудь, и я повторю.")
@dp.message()
async def echo(message: Message):
# повторяем любое другое сообщение
await message.send_copy(chat_id=message.chat.id)
async def main():
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.
Шаг 4. Проверьте бота вручную
Перед тем как настраивать автозапуск, убедитесь, что бот работает. Команда read -s спросит токен и не покажет его на экране, поэтому он не останется в истории команд. Вставьте токен и нажмите Enter.
read -s -p "Токен: " BOT_TOKEN; export BOT_TOKEN
venv/bin/python bot.pyЕсли всё в порядке, появятся строки Start polling и Run polling for bot с адресом вашего бота.

Бот запущен и обработал два сообщения
Откройте бота в Telegram по ссылке от BotFather, отправьте ему /start, а затем любое сообщение.

Бот отвечает на /start и повторяет сообщения
Остановите бота сочетанием Ctrl + C и вернитесь в root командой exit.
Шаг 5. Настройте автозапуск
Сейчас бот работает, только пока открыт терминал. Оформим его как службу systemd, тогда он будет запускаться вместе с сервером и подниматься после сбоев. Подробнее о службах рассказано в статье про systemd.
Сначала сохраните токен в файл, который может прочитать только root. Замените ВАШ_ТОКЕН на токен от BotFather.
echo "BOT_TOKEN=ВАШ_ТОКЕН" > /etc/tgbot.env
chmod 600 /etc/tgbot.envЗатем создайте службу.
nano /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
ExecStart=/opt/tgbot/venv/bin/python bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetСтрока EnvironmentFile передаёт боту токен из файла. systemd читает этот файл от имени root ещё до запуска бота, поэтому самому пользователю tgbot доступ к нему не нужен.
Включите автозапуск и запустите бота.
systemctl daemon-reload
systemctl enable --now tgbot
systemctl status tgbot
Бот работает как служба
На нашем сервере служба с этим ботом занимала около 150 МБ памяти по данным systemctl status.
Как обновлять бота и смотреть логи
- Изменили код. Отредактируйте
/opt/tgbot/bot.pyи перезапустите службу командойsystemctl restart tgbot. - Добавили библиотеку. Установите её в окружение бота командой
su - tgbot -c "venv/bin/pip install имя"и перезапустите службу. - Логи. Всё, что бот пишет в консоль, попадает в журнал. Последние строки показывает
journalctl -u tgbot -n 50, а следить в реальном времени можно командойjournalctl -u tgbot -f. Подробнее о журнале рассказано в статье про логи Linux.
Частые вопросы
The virtual environment was not created successfully because ensurepip is not available
Не установлен пакет python3-venv. Мы получили эту ошибку на чистом Debian 12. Установите пакет командой apt install -y python3-venv, удалите неудачную папку командой rm -rf venv и создайте окружение заново.

Python подсказывает, какой пакет установить
TelegramUnauthorizedError: Telegram server says - Unauthorized
Telegram не принял токен. Скорее всего, он скопирован не полностью или с лишним пробелом, либо был отозван командой /revoke. Проверьте строку в /etc/tgbot.env или получите новый токен у BotFather.

Так выглядит ответ Telegram на неверный токен
TelegramConflictError: terminated by other getUpdates request
С этим токеном одновременно работают две копии бота. Мы получили эту ошибку, когда запустили бота вручную, пока работала служба. Обычно вторая копия осталась в другом окне терминала, в screen или на другом сервере. Остановите лишнюю копию. Когда она завершилась, служба на нашем сервере снова подключилась сама.

Telegram требует, чтобы работала только одна копия бота
ModuleNotFoundError: No module named 'aiogram'
Бот запущен системным Python, а не Python из окружения. Мы получили эту ошибку, запустив бота командой python3 bot.py. Запускайте его командой venv/bin/python bot.py, а в службе указывайте полный путь /opt/tgbot/venv/bin/python.
Бот не отвечает
- Проверьте, что служба работает, командой
systemctl status tgbot. - Посмотрите последние строки журнала командой
journalctl -u tgbot -n 50. Там будет ошибка, из-за которой бот остановился. - Убедитесь, что не запущена вторая копия бота с тем же токеном.
Наши ресурсы
Telegram-канал: https://t.me/f3cloud_news
Официальный сайт: https://f3cloud.com