VPS для Telegram-бота: минимальный тариф, Docker и автозапуск
Telegram-бот редко нуждается в «тяжёлом» сервере. Ему важнее другое: стабильный исходящий доступ к Bot API, предсказуемый автозапуск после ребута и чтобы токен не уехал в git. Ниже — узкий сценарий: как выбрать минимальный тариф, поднять бота в Docker Compose, закрыть лишнее firewall’ом и не пропустить падение. Без общего курса по Ubuntu и Docker — только то, что реально нужно боту на VPS.
Если сервер ещё не подготовлен (SSH-ключи, обновления, базовый firewall), начните с настройки Ubuntu: безопасность, Docker, firewall. Подключиться с любой ОС поможет гайд по SSH. Здесь же — от выбора polling/webhook до мониторинга и посуточного теста.
Polling или webhook — что выбрать на VPS
Telegram отдаёт обновления двумя способами. Long polling: ваш процесс сам ходит в getUpdates и ждёт события. Webhook: Telegram стучится на ваш HTTPS-endpoint, когда приходит сообщение.
Для большинства ботов на одном VPS polling проще:
- не нужен домен и TLS-сертификат;
- не нужно открывать 443 наружу под webhook;
- меньше точек отказа на старте (DNS, Certbot, reverse proxy).
Webhook оправдан, когда:
- нагрузка высокая и вы хотите мгновенную доставку без постоянного опроса;
- бот уже стоит за reverse proxy с нормальным HTTPS;
- несколько инстансов и вы осознанно проектируете входящий трафик.
На минимальном тарифе под личный или небольшой рабочий бот polling почти всегда выигрывает по простоте. Webhook добавьте позже, когда появятся домен, nginx/caddy и понятный health-check. Не смешивайте оба режима на одном токене: Telegram принимает либо polling, либо webhook.
Практичный порядок: сначала polling в Docker с restart: unless-stopped, убедиться, что бот отвечает, логи чистые. Потом — если нужно — вынести webhook за HTTPS и закрыть лишние порты.
Минимальные ресурсы под бота
Типичный бот на Python (aiogram/python-telegram-bot) или Node — это лёгкий процесс: сеть к api.telegram.org, иногда SQLite или маленький Redis, редко тяжёлая БД на той же машине.
Ориентиры для одного бота без тяжёлой аналитики:
- 1 vCPU — достаточно, пока нет CPU-bound задач (видео, OCR, массовая генерация);
- 1 ГБ RAM — комфортный минимум под Docker + один контейнер бота; 512 МБ тоже живут, но запас на пики и обновления тоньше;
- 10–20 ГБ диска — хватает ОС, образа и логов, если не копить том логирования без ротации;
- исходящий HTTPS к Bot API — критичнее «сырых» ядер.
Когда ресурсов мало не хватает:
- в контейнере крутятся ещё Postgres, Elasticsearch, тяжёлый браузерный headless;
- бот шлёт медиа потоком и пишет на диск без очистки;
- вы держите несколько ботов на одной машине без лимитов памяти.
Если бот только отвечает на команды и пишет в SQLite — младший тариф с запасом. Если рядом полноценный бэкенд сайта — считайте ресурсы сайта отдельно и не «натягивайте» всё на одну виртуалку «для экономии», пока не измерите нагрузку.
Выдача VPS у AZERTA — до 120 секунд после оплаты, тарифы от 360₽, поддержка 24/7. Для постоянной работы смотрите линейку на /vps/, для тестов удобнее посуточная аренда.
Скелет Docker Compose
Идея простая: один сервис бота, переменные окружения из файла вне git, политика перезапуска, ограничение логов. Ниже — универсальный каркас под Python или Node: меняете образ и команду, логика та же.
Структура каталога:
bot/
docker-compose.yml
.env # не в git
.env.example
Dockerfile # или готовый образ
app/ # код
Пример docker-compose.yml:
services:
bot:
build: .
# image: ghcr.io/your-org/telegram-bot:latest
container_name: tg-bot
restart: unless-stopped
env_file:
- .env
environment:
TZ: Europe/Moscow
# Для webhook раскомментируйте и пробросьте порт:
# ports:
# - "127.0.0.1:8080:8080"
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# Опционально: лимит памяти, чтобы один утекающий процесс не уронил весь VPS
mem_limit: 512m
Минимальный .env (пример, не копируйте токены в чаты):
BOT_TOKEN=123456:ABC-DEF...
# DATABASE_URL=sqlite:////data/bot.db
.env.example без секретов кладите в репозиторий. Сам .env — в .gitignore.
Запуск:
cd bot
docker compose up -d --build
docker compose ps
docker compose logs -f --tail=100
Dockerfile оставляем минимальным: multi-stage не обязателен на старте, важнее не запускать от root без нужды и не класть .env в образ через COPY. Секреты — только runtime (env_file / secrets Docker).
Если нужен reverse proxy под webhook — это уже отдельный сервис в том же compose или на хосте. Базовая установка Docker и firewall описана в статье по Ubuntu; здесь не дублируем полный гайд.
Для черновика бота удобен VPS под разработку: подняли стенд, прогнали compose, снесли или оставили. Когда стабилизируется — тот же compose переносится на постоянный тариф без смены подхода.
Автозапуск и логи
restart: unless-stopped в Compose — база: контейнер поднимется после ребута VPS и после падения процесса, пока вы сами его не остановили (docker compose stop).
Проверка после reboot:
sudo reboot
# после входа:
docker compose -f /path/to/bot/docker-compose.yml ps
docker compose logs --tail=50
Если Docker установлен штатно, сервис docker обычно в автозагрузке. Имеет смысл один раз проверить:
systemctl is-enabled docker
systemctl status docker --no-pager
Логи:
docker compose logs -f— основной инструмент в повседневке;docker logs tg-bot --since 1h— если смотрите по имени контейнера;- ротация через
logging.optionsв compose (см. выше) — иначе json-логи съедят диск.
На хосте journald тоже растёт. Если крутите unit’ы вне Docker, смотрите journalctl -u your-bot -f. Для контейнерного сценария чаще хватает docker logs + лимиты размера.
Не путайте «контейнер Up» и «бот реально отвечает». После деплоя отправьте тестовое сообщение в Telegram и убедитесь, что в логах нет бесконечных reconnect/timeout к API.
Секреты и firewall
Токен не в git и не в образе
Token BotFather — полный доступ к боту. Утечка = чужой спам от вашего имени, кража данных пользователей, отзыв токена в спешке.
Правила:
BOT_TOKENтолько в.envили Docker/ Swarm/ CI secrets;.envв.gitignore; в CI — секреты пайплайна, не переменные в открытом YAML;- не коммитьте скриншоты с токеном и не светите его в issue;
- при утечке — сразу
/revokeв BotFather и новый токен в.env, затемdocker compose up -d.
Права на файл:
chmod 600 .env
chown "$USER":"$USER" .env
Firewall: только нужное
Для бота на polling снаружи обычно нужен только SSH (лучше по ключу, не паролем). HTTPS наружу — если webhook или свой веб-интерфейс.
Минимальный UFW:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
# только если webhook / свой сайт на этой машине:
# sudo ufw allow 80/tcp
# sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Исходящий HTTPS к Telegram не блокируйте: боту нужен доступ к api.telegram.org. Входящий 443 без webhook открывать незачем.
Дополнительно к SSH имеет смысл Fail2ban, если оставляете 22/tcp в мир. Ключи вместо пароля — обязательный минимум из гайда по настройке VPS.
Не публикуйте порт приложения бота в 0.0.0.0, если webhook идёт через локальный reverse proxy: в compose достаточно 127.0.0.1:8080:8080.
Москва или Германия для Bot API
Bot API Telegram — глобальный сервис. Для бота важнее стабильный маршрут и отсутствие блокировок исходящего HTTPS, чем «магический» выбор города в панели.
Практично:
- Москва (ДЦ Нагатинский) — удобно, если вы и пользователи в РФ, проще совмещать бота с другими сервисами на той же площадке, привычный TZ в логах (
Europe/Moscow). - Германия (DE) — нормальный вариант, когда нужен европейский сегмент или вы уже держите там остальные сервисы. Точный адрес ЦОД для выбора «пинга до Telegram» обычно не критичен: важнее измерить именно ваш канал.
Не опирайтесь на чужие скриншоты ping. С вашего VPS после выдачи проверьте сами:
curl -o /dev/null -s -w "%{http_code} time=%{time_total}\n" https://api.telegram.org
# или несколько раз:
for i in 1 2 3 4 5; do
curl -s -o /dev/null -w "%{time_connect} %{time_total}\n" https://api.telegram.org
done
Смотрите не «идеальные миллисекунды», а стабильность: нет ли таймаутов, обрывов TLS, долгих зависаний getUpdates. Если polling стабилен часами — локация для вашего кейса подходит. Если есть странные обрывы — смените площадку или проверьте firewall/MTU, а не увеличивайте тариф «на всякий случай».
Пользователи бота общаются с Telegram-клиентами; ваш VPS общается с API. Latency «Москва vs DE» редко решает UX чата — чаще решают баги обработчиков и рестарты без restart-политики.
Мониторинг падений
«Контейнер Up» в docker ps не равен «бот отвечает в Telegram». Нужен хотя бы один внешний сигнал.
Минимальный набор:
- Health внутри кода — периодический успешный
getMe/ свой heartbeat в лог. - Внешний uptime — HTTP health, если есть webhook/веб; для чистого polling — отдельная проверка «процесс жив» + алерт по отсутствию логов/метрик.
- Диск и память — бот молчит, когда диск 100% или OOM убил процесс.
Краткая проверка с хоста:
docker compose ps
docker compose logs --tail=20
df -h /
free -h
Для системного взгляда (uptime снаружи, диск, CPU) — мониторинг VPS: uptime, диск, CPU. Имеет смысл повесить алерт в Telegram… другим ботом или через канал уведомлений: ирония в том, что один бот может сообщить о смерти другого, если крутятся на разных машинах или хотя бы внешний SaaS пингует health.
Простой cron-heartbeat (идея): раз в 5 минут скрипт дергает API или смотрит docker inspect на Status и OOMKilled, при сбое пишет в запасной канал. Не усложняйте до Prometheus в первый день — сначала стабильный restart и один алерт.
Когда хватит младшего тарифа и посуточно для тестов
Младшего тарифа обычно хватает, если:
- один бот, polling, без тяжёлой БД на той же VM;
- нет массовой рассылки на десятки тысяч чатов с медиа;
- логи ротируются, диск не забит бэкапами «на всякий»;
- нет параллельного «ещё и интернет-магазин на этом же VPS».
Имеет смысл апгрейд, когда стабильно упираетесь в RAM (OOM), CPU на обработчиках или диск из‑за данных — не когда «вдруг завтра хайп».
Посуточно ([/vps/daily/](/vps/daily/)) отлично подходит, чтобы:
- проверить Docker Compose и автозапуск «с нуля» за один вечер;
- сравнить Москву и DE на своём коде без обязательства на месяц;
- отдать стенд подрядчику на пару дней.
Под разработку ([/vps/development/](/vps/development/)) — когда бот ещё пишется: частые пересборки образа, эксперименты с webhook, временные домены. Когда пайплайн устоялся — тот же compose на постоянный /vps/.
Напоминание по продукту AZERTA (без выдуманных опций): выдача до 120 секунд после оплаты, тарифы от 360₽, работа 24/7, площадки — Москва (Нагатинский) и Германия. После 3 ТБ трафика действует шейпинг 1 Мбит/с — для обычного текстового бота это обычно далеко за горизонтом; упираются чаще те, кто гоняет крупные файлы или зеркала.
FAQ
Нужен ли домен для Telegram-бота на VPS?
Для polling — нет. Для webhook — да (или хотя бы валидный HTTPS на IP с сертификатом, что на практике неудобнее домена). На старте проще polling без домена.
Сколько RAM нужно боту в Docker?
Часто хватает 512 МБ–1 ГБ на лёгкий Python/Node-бот плюс ОС. Держите запас: обновления пакетов, пик при деплое, утечки. Лимит mem_limit в compose защищает хост от одного «поехавшего» процесса.
Polling безопаснее webhook?
Разные модели угроз. Polling не открывает входящий HTTP под бота — меньше поверхность. Webhook требует TLS и аккуратного firewall. Безопасность токена и SSH важнее выбора режима.
Что делать, если бот «молчит», а контейнер Up?
Смотрите docker compose logs, проверьте токен и доступ к api.telegram.org, нет ли webhook, забытого на старом URL (deleteWebhook), не упёрлись ли в диск/OOM. Отправьте тестовое сообщение и сверьте latency запросов к API.
Можно ли держать несколько ботов на одном VPS?
Да: отдельные сервисы в compose или отдельные compose-проекты, разные .env, лимиты памяти. Следите за суммарной RAM и за тем, чтобы логи не писались без ротации. Изоляция секретов — по боту, не один общий .env на всех.
Посуточный VPS подойдёт для продакшена?
Для продакшена удобнее постоянный тариф с предсказуемым биллингом. Посуточно — стенды, тесты, сравнение локаций, демо клиенту. Рабочий бот лучше перенести на обычный /vps/, сохранив тот же Docker-стек.
Итоговый путь короткий: polling на минимальном тарифе → Compose с restart и .env вне git → UFW только под SSH (и 443, если webhook) → простой мониторинг падений → посуточный стенд для проверки, постоянный VPS для боя. Когда базовая ОС и Docker ещё не настроены, вернитесь к гайду по Ubuntu и SSH; когда бот уже крутится — к мониторингу, чтобы узнавать о падении раньше пользователей в чате.