TürkiyeVPS

Запуск Telegram-бота 24/7 на VPS через systemd

Бот не должен засыпать вместе с ноутбуком. Пошагово: запуск Telegram-бота на Python 24/7 на VPS с Ubuntu 24.04 через systemd, хранение токена и просмотр логов.

6 мин чтения

Бот написан, на домашнем компьютере всё работает. Но стоит закрыть крышку ноутбука, потерять Wi-Fi или дождаться очередной перезагрузки Windows — и бот замолкает, а пользователи ждут ответа. В этой статье разберём, как организовать запуск Telegram-бота 24/7 на VPS правильно: отдельный пользователь, виртуальное окружение Python, токен вне кода и сервис systemd, который сам поднимет бота после падения. Команды написаны для Ubuntu 24.04 и так же работают на Debian 12.

Почему VPS, а не домашний ПК

  • Работа без перерывов: VPS крутится на сервере в дата-центре, который не выключается. Отключение света дома или перезагрузка роутера бота не затрагивают.
  • Стабильный канал и IP: у домашнего интернета IP меняется, соединение рвётся; на сервере всё предсказуемее.
  • Компьютер свободен: не нужно держать ноутбук включённым круглые сутки.
  • Невысокая цена: простому боту нужно очень мало ресурсов, поэтому для большинства проектов хватает небольшого Linux VPS. Аренда VPS под бота обычно стоит дешевле, чем кажется.

Общий подход к запуску Python-приложений на сервере мы описали в статье Python-приложение на VPS. Здесь — конкретно про Telegram-бота и systemd.

Шаг 1. Создайте бота в BotFather и получите токен

Откройте в Telegram @BotFather, отправьте /newbot, задайте имя и username, оканчивающийся на _bot. В ответ придёт токен вида:

123456789:AAF...длинная-случайная-строка

Токен — это пароль от бота. Не вшивайте его в код, не заливайте на GitHub, не светите на скриншотах. Если он утёк, выпустите новый командой /revoke в BotFather.

Шаг 2. Подготовьте сервер

Подключитесь по SSH или через веб-терминал в личном кабинете и обновите систему:

sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-venv python3-pip git

Отдельный пользователь для бота

Запускать бота от root — лишний риск: уязвимость в вашем коде или в зависимости может отдать злоумышленнику весь сервер. Создадим системного пользователя без возможности входа:

sudo adduser --system --group --home /opt/telegram-bot botuser

Команда создаёт пользователя botuser без пароля и без оболочки входа, а также каталог /opt/telegram-bot.

Шаг 3. Виртуальное окружение и библиотека

У бота будет собственный venv, системный Python мы не трогаем. В Ubuntu 24.04 глобальный pip install и так заблокирован, так что venv — правильный путь:

sudo -u botuser python3 -m venv /opt/telegram-bot/venv
sudo -u botuser /opt/telegram-bot/venv/bin/pip install --upgrade pip
sudo -u botuser /opt/telegram-bot/venv/bin/pip install "python-telegram-bot>=21"

Начиная с версии 20 библиотека python-telegram-bot полностью асинхронная. Пример ниже рассчитан на версии 21 и новее.

Шаг 4. Минимальный бот

Создайте файл:

sudo nano /opt/telegram-bot/bot.py

Вставьте код:

import logging
import os

from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters

logging.basicConfig(
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    level=logging.INFO,
)

TOKEN = os.environ["BOT_TOKEN"]


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.effective_message.reply_text("Привет! Этот бот работает 24/7 на VPS.")


async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.effective_message.reply_text(update.effective_message.text)


def main() -> None:
    app = Application.builder().token(TOKEN).build()
    app.add_handler(CommandHandler("start", start))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
    app.run_polling(allowed_updates=Update.ALL_TYPES)


if __name__ == "__main__":
    main()

Передайте файл пользователю бота:

sudo chown botuser:botuser /opt/telegram-bot/bot.py

Обратите внимание: токена в коде нет, он читается из переменной окружения BOT_TOKEN.

Шаг 5. Храните токен в защищённом файле

sudo nano /etc/telegram-bot.env

Одна строка, без кавычек:

BOT_TOKEN=123456789:AAF...ваш-токен

Доступ — только для root:

sudo chown root:root /etc/telegram-bot.env
sudo chmod 600 /etc/telegram-bot.env

systemd читает файл от имени root при старте сервиса и передаёт переменную боту. Сам botuser прочитать файл не может.

Шаг 6. Создайте сервис systemd

Это ключевая часть. systemd запускает бота при загрузке, перезапускает при сбое и собирает вывод в журнал.

sudo nano /etc/systemd/system/telegram-bot.service
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=botuser
Group=botuser
WorkingDirectory=/opt/telegram-bot
EnvironmentFile=/etc/telegram-bot.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/telegram-bot/venv/bin/python /opt/telegram-bot/bot.py
Restart=always
RestartSec=5

# Базовое усиление безопасности
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/telegram-bot

[Install]
WantedBy=multi-user.target

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

  • Restart=always и RestartSec=5 — что бы ни остановило бота, через 5 секунд он запустится снова.
  • PYTHONUNBUFFERED=1 — вывод Python сразу попадает в журнал, без буферизации.
  • ProtectSystem=strict и ReadWritePaths — бот не может писать в системные файлы, только в свой каталог. Базу SQLite и прочие данные храните в /opt/telegram-bot.
  • NoNewPrivileges=true — процесс не сможет получить дополнительные привилегии.

Шаг 7. Запуск и логи

sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
sudo systemctl status telegram-bot

Видите active (running) — напишите боту /start. Журнал в реальном времени:

sudo journalctl -u telegram-bot -f

Последние 100 строк: sudo journalctl -u telegram-bot -n 100 --no-pager. Другие полезные команды собраны в статье команды для управления сервером.

Проверим автоперезапуск: принудительно завершим процесс и посмотрим статус через несколько секунд.

sudo systemctl kill telegram-bot
sleep 6
sudo systemctl status telegram-bot

Обновление кода

Если код лежит в Git, клонируйте репозиторий в /opt/telegram-bot от имени botuser. Обновление — две команды:

sudo -u botuser git -C /opt/telegram-bot pull
sudo systemctl restart telegram-bot

Добавили зависимость — сначала установите её:

sudo -u botuser /opt/telegram-bot/venv/bin/pip install -r /opt/telegram-bot/requirements.txt

После правки самого unit-файла не забудьте sudo systemctl daemon-reload.

Polling или webhook?

Наш бот работает через long polling: он сам регулярно спрашивает у серверов Telegram, есть ли новые сообщения. Плюс в том, что не нужно открывать входящие порты, не нужен ни домен, ни SSL-сертификат. Для большинства ботов этого более чем достаточно.

При webhook Telegram сам отправляет каждое обновление на HTTPS-адрес вашего сервера. Это удобно для нагруженных ботов, но потребуются домен, действительный сертификат и веб-сервер. Как всё это настроить, рассказано в гайде Nginx и SSL от Let's Encrypt.

То же самое для Node.js и Discord-ботов

systemd всё равно, на каком языке написан бот. Для Node.js меняется только ExecStart:

ExecStart=/usr/bin/node /opt/telegram-bot/index.js

Так же запускаются Discord-боты, юзерботы и небольшие скрипты по расписанию. Для каждого бота — свой unit-файл (например, discord-bot.service) и свой env-файл.

Сколько ресурсов нужно боту

Простой бот «команда — ответ» обычно занимает несколько десятков мегабайт RAM и почти не нагружает процессор, так что стартового VPS хватает с запасом. Если бот обрабатывает изображения, качает большие файлы, активно обращается к AI API или держит базу данных — закладывайте больше памяти. Потребление RAM и CPU видно в личном кабинете.

Часто задаваемые вопросы

Что будет, если бот упадёт?

Благодаря Restart=always systemd перезапустит его за несколько секунд. После перезагрузки сервера бот стартует автоматически, потому что сервис включён через enable. Причину сбоя ищите в journalctl -u telegram-bot.

Можно ли держать несколько ботов на одном сервере?

Да. У каждого бота должны быть свой каталог, свой env-файл и свой сервис (bot1.service, bot2.service и т. д.). Следите только за общим расходом памяти.

Разве screen или tmux недостаточно?

Для быстрых тестов — достаточно. Но после перезагрузки бот сам не поднимется, а при падении его никто не перезапустит. Для постоянной работы systemd надёжнее.

Сервер для вашего бота

VPS в Турции от TürkiyeVPS — это сервер в Стамбуле от $0.89 в месяц: Ubuntu 24.04 или Debian 12, полный root-доступ и безлимитный трафик. Сервер разворачивается автоматически сразу после подтверждения оплаты (сейчас принимаем USDT в сети TRC20), подключиться можно через веб-терминал в личном кабинете. Если возникнут вопросы — пишите в онлайн-чат на сайте или создайте тикет в поддержку.