MHOSTMHOST

Как запустить 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 -y
apt install -y python3 python3-venv python3-pip git

adduser --disabled-password --gecos "" bot

Проверьте версию Python: python3 --version. Для aiogram 3 нужен Python 3.9 или новее, в Ubuntu 22.04 и 24.04 он уже подходящий.

Шаг 2. Загрузите код бота и установите зависимости

Переключитесь на пользователя bot и перенесите код на сервер. Удобнее всего через Git:

su - bot
git clone https://github.com/ВАШ_АККАУНТ/ВАШ_БОТ.git mybot

cd mybot

Если репозитория нет, скопируйте файлы со своего компьютера: scp -r ./mybot bot@IP_СЕРВЕРА:~/.

Создайте виртуальное окружение и установите библиотеки. Окружение изолирует зависимости бота от системного Python:

python3 -m venv venv
source venv/bin/activate
pip install aiogram python-dotenv
pip freeze > requirements.txt

Токен храните в файле .env, а не в коде. Иначе он попадёт в Git, и любой, кто увидит репозиторий, получит управление ботом.

echo 'BOT_TOKEN=123456789:AAH...' > .env
chmod 600 .env

Пример минимального бота bot.py, если хотите проверить запуск:

import asyncio
import os

from aiogram import Bot, Dispatcher
from aiogram.filters import CommandStart
from aiogram.types import Message
from dotenv import load_dotenv

load_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 bot
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=bot
WorkingDirectory=/home/bot/mybot
ExecStart=/home/bot/mybot/venv/bin/python bot.py
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

Что здесь важно:

  • ExecStart указывает на Python из виртуального окружения. Так бот видит установленные библиотеки.
  • Restart=always и RestartSec=5 перезапускают бота через 5 секунд после падения.
  • PYTHONUNBUFFERED=1 выводит логи сразу, без задержки.

Включите и запустите службу:

systemctl daemon-reload
systemctl enable --now mybot
systemctl 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/bash
set -e
cd /home/bot/mybot
sudo -u bot git pull
sudo -u bot ./venv/bin/pip install -r requirements.txt
systemctl restart mybot
systemctl 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:

  1. Направьте домен или поддомен на IP сервера.
  2. Установите Nginx и получите SSL-сертификат Let's Encrypt через Certbot.
  3. Настройте в Nginx проксирование пути, например /webhook, на локальный порт бота.
  4. В коде бота замените 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 -I https://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, подождите минуту и напишите боту. Если он ответил, автозапуск работает.