Как запустить Telegram-бота на VPS 24/7: пошаговая инструкция
Чтобы Telegram-бот отвечал круглосуточно, его нужно запустить на сервере, который не выключается. Самый простой и дешёвый вариант — VPS с автозапуском бота через systemd.
На домашнем компьютере бот останавливается, стоит закрыть ноутбук или потерять интернет. Бесплатные платформы усыпляют приложения без активности и ограничивают часы работы. На VPS бот работает постоянно, сам перезапускается после сбоя и стартует после перезагрузки сервера.
В инструкции разберём запуск бота на Python (aiogram 3) на Ubuntu 22.04/24.04. Для ботов на Node.js шаги те же, отличается только команда запуска.
Что понадобится
- VPS. Для обычного бота хватит 1 vCPU и 1 ГБ RAM. Если бот работает с базой данных, обрабатывает файлы или обслуживает тысячи пользователей, берите 2 ГБ RAM и больше.
- ОС Ubuntu 22.04 или 24.04.
- Токен бота. Напишите @BotFather в Telegram, отправьте
/newbot, задайте имя и username. BotFather пришлёт токен вида123456789:AAH.... - Доступ по SSH к серверу. Логин и пароль или ключ выдаёт хостинг после покупки.
Локация сервера имеет значение. Выбирайте страну, где Telegram не блокируется, иначе бот не сможет подключиться к API.
Шаг 1. Подготовьте сервер
Подключитесь к VPS, обновите систему и создайте отдельного пользователя для бота. Запускать бота от root небезопасно: при уязвимости в коде злоумышленник получит полный доступ к серверу.
ssh root@IP_СЕРВЕРАapt update && apt upgrade -yapt install -y python3 python3-venv python3-pip gitadduser --disabled-password --gecos "" bot
Проверьте версию Python: python3 --version. Для aiogram 3 нужен Python 3.9 или новее, в Ubuntu 22.04 и 24.04 он уже подходящий.
Шаг 2. Загрузите код бота и установите зависимости
Переключитесь на пользователя bot и перенесите код на сервер. Удобнее всего через Git:
su - botgit clone https://github.com/ВАШ_АККАУНТ/ВАШ_БОТ.git mybotcd mybot
Если репозитория нет, скопируйте файлы со своего компьютера: scp -r ./mybot bot@IP_СЕРВЕРА:~/.
Создайте виртуальное окружение и установите библиотеки. Окружение изолирует зависимости бота от системного Python:
python3 -m venv venvsource venv/bin/activatepip install aiogram python-dotenvpip freeze > requirements.txt
Токен храните в файле .env, а не в коде. Иначе он попадёт в Git, и любой, кто увидит репозиторий, получит управление ботом.
echo 'BOT_TOKEN=123456789:AAH...' > .envchmod 600 .env
Пример минимального бота bot.py, если хотите проверить запуск:
import asyncioimport osfrom aiogram import Bot, Dispatcherfrom aiogram.filters import CommandStartfrom aiogram.types import Messagefrom dotenv import load_dotenvload_dotenv()bot = Bot(token=os.getenv("BOT_TOKEN"))dp = Dispatcher()@dp.message(CommandStart())async def start(message: Message): await message.answer("Бот работает на VPS 24/7!")@dp.message()async def echo(message: Message): await message.send_copy(chat_id=message.chat.id)async def main(): await dp.start_polling(bot)if __name__ == "__main__": asyncio.run(main())
Проверьте вручную: python bot.py. Напишите боту /start — он должен ответить. Остановите бота через Ctrl+C и выйдите из пользователя командой exit.
Шаг 3. Запустите бота 24/7 через systemd
Если запустить бота командой python bot.py, он остановится при закрытии SSH-сессии. systemd запускает бота как службу: в фоне, с автоматическим перезапуском после сбоя и после перезагрузки сервера.
Создайте файл службы от root:
nano /etc/systemd/system/mybot.service
[Unit]Description=Telegram botAfter=network-online.targetWants=network-online.target[Service]Type=simpleUser=botWorkingDirectory=/home/bot/mybotExecStart=/home/bot/mybot/venv/bin/python bot.pyRestart=alwaysRestartSec=5Environment=PYTHONUNBUFFERED=1
[Install]WantedBy=multi-user.target
Что здесь важно:
ExecStartуказывает на Python из виртуального окружения. Так бот видит установленные библиотеки.Restart=alwaysиRestartSec=5перезапускают бота через 5 секунд после падения.PYTHONUNBUFFERED=1выводит логи сразу, без задержки.
Включите и запустите службу:
systemctl daemon-reloadsystemctl enable --now mybotsystemctl status mybot
Статус active (running) означает, что бот работает. Логи в реальном времени: journalctl -u mybot -f.
Для бота на Node.js замените строку запуска: ExecStart=/usr/bin/node bot.js. Путь к Node.js покажет команда which node.
Шаг 4. Обновляйте бота одной командой
После изменений в коде нужно подтянуть новую версию, обновить зависимости и перезапустить службу. Удобно собрать это в скрипт /home/bot/mybot/deploy.sh:
#!/bin/bashset -ecd /home/bot/mybotsudo -u bot git pullsudo -u bot ./venv/bin/pip install -r requirements.txtsystemctl restart mybotsystemctl status mybot --no-pager
Сделайте скрипт исполняемым и запускайте от root:
chmod +x /home/bot/mybot/deploy.sh/home/bot/mybot/deploy.sh
Остальные полезные команды:
systemctl stop mybot— остановить бота.systemctl restart mybot— перезапустить.journalctl -u mybot -n 100— последние 100 строк логов.
Polling или webhook: что выбрать
Для большинства ботов достаточно polling, который мы настроили выше. Webhook нужен, когда пользователей много и важна скорость ответа.
- Polling. Бот сам регулярно спрашивает у Telegram новые сообщения. Не нужны домен, SSL и открытые порты. Подходит для личных ботов и ботов с аудиторией до нескольких тысяч человек.
- Webhook. Telegram сам отправляет сообщения на ваш сервер. Ответ быстрее, нагрузка ниже, но нужен домен с HTTPS. Telegram принимает webhook только на портах 443, 80, 88 и 8443.
Чтобы перейти на webhook:
- Направьте домен или поддомен на IP сервера.
- Установите Nginx и получите SSL-сертификат Let's Encrypt через Certbot.
- Настройте в Nginx проксирование пути, например
/webhook, на локальный порт бота. - В коде бота замените
start_pollingна запуск веб-сервера и вызовset_webhookс адресомhttps://ваш-домен/webhook.
В aiogram 3 для этого есть готовый модуль aiogram.webhook.aiohttp_server, пример есть в документации библиотеки.
Частые ошибки и как их исправить
- Бот останавливается после закрытия SSH. Его запустили командой
python bot.py, а не службой. Запускайте через systemd, как в шаге 3. ModuleNotFoundError: No module named 'aiogram'. Служба использует системный Python вместо виртуального окружения. Проверьте, что вExecStartуказан путь.../venv/bin/python.TelegramConflictError: terminated by other getUpdates request. Бот запущен дважды: например, на сервере и на вашем компьютере, или вручную параллельно со службой. Оставьте один экземпляр.- Бот не отвечает, в логах таймауты. Сервер не может подключиться к Telegram API. Проверьте:
curl -Ihttps://api.telegram.org. Если соединения нет, выберите VPS в другой локации. - Служба не стартует. Посмотрите причину в логах:
journalctl -u mybot -n 50. Чаще всего это опечатка в пути или нет прав на папку у пользователяbot. - Токен утёк. Отправьте @BotFather команду
/revoke, получите новый токен и замените его в.env.
Чек-лист
Частые вопросы
Сколько ресурсов нужно Telegram-боту? Простому боту хватает 1 vCPU и 1 ГБ RAM, на одном таком VPS можно держать несколько ботов. Больше ресурсов нужно ботам с базой данных, обработкой медиа или нейросетями.
Можно ли запустить несколько ботов на одном VPS? Да. Для каждого бота создайте отдельную папку, своё виртуальное окружение и свою службу systemd: bot1.service, bot2.service и так далее.
Что лучше: systemd, screen, pm2 или Docker? systemd уже есть в Ubuntu и перезапускает бота после сбоев и перезагрузок. screen такого не умеет. pm2 удобен для Node.js, а Docker — если бот состоит из нескольких сервисов, например бот плюс база данных.
Нужен ли домен для бота? Для polling — нет. Домен с HTTPS нужен только для webhook.
Как проверить, что бот переживёт перезагрузку сервера? Выполните reboot, подождите минуту и напишите боту. Если он ответил, автозапуск работает.