сайт в бете
нашли баг? напишите
левин. записаться
весь блог

Переезд бота на VPS: чек-лист, после которого он живёт без тебя

Бот на ноутбуке работает, пока ты рядом: сам видишь трейсбек, сам перезапускаешь. На сервере этого человека нет — его обязанности приходится раздать машине. Разбираю по шагам, что именно нужно настроить.

Л
Проект Левин
автор

Ноутбук закрыл — бот умер. Пока ты сидишь рядом, мониторинг — это ты сам: увидел трейсбек в терминале, руками поднял упавший процесс, подложил новый токен. На VPS такого человека нет. Все его обязанности придётся раздать машине, по пунктам, ничего не пропуская.

Порядок ниже собрался сам собой, когда я переносил на сервер бота для проверки вывесок, меню и рекламы на соответствие 168-ФЗ о русском языке. Стек обычный: aiogram 3, httpx, SQLite через aiosqlite, конфиг на pydantic-settings.

Шаг 1. Зафиксировать зависимости и конфиг

«У меня локально работало» — самая частая поломка при переезде. Лечится двумя файлами.

requirements.txt — с версиями. У меня это нижние границы вида aiogram>=3.20, openai>=1.30, aiosqlite>=0.20. Удобно, пока обновляешься сам. Нужна полная предсказуемость на сервере — фиксируй точные версии через pip freeze.

.env.example — пустой шаблон со всеми переменными, лежит в репозитории. Реальный .env с токенами в git не попадает никогда. На сервере копируешь шаблон и заполняешь:

cp .env.example .env

Читать переменные лучше через pydantic-settings. Забыл ключ — бот падает на старте с внятным сообщением. Альтернатива: None всплывёт где-то в середине обработчика через два дня.

Шаг 2. Докер вместо «поставил питон руками»

Вручную поставленный Python на сервере — отдельная сущность, которую надо помнить и обслуживать. Проще упаковать всё в контейнер:

docker compose up -d --build
docker compose logs -f

Одна строчка в docker-compose.yml делает половину работы за тебя:

restart: unless-stopped

Бот сам поднимется после падения, после docker restart и после перезагрузки сервера. Первая обязанность с тебя снята.

Шаг 3. Данные должны пережить пересборку

База SQLite внутри контейнера умрёт при следующем --build вместе со всей историей пользователей. Выноси файл базы в volume:

volumes:
  - ./data:/app/data

И сразу подумай про бэкап. Для SQLite хватит cron-задачи, которая раз в сутки копирует файл базы в отдельную папку. Копируй через sqlite3 base.db ".backup copy.db" — обычный cp может поймать базу в момент записи.

Шаг 4. Один бот — один процесс

На long polling два запущенных экземпляра начинают драться за getUpdates. Симптом узнаваемый: сообщения приходят через раз, в логах — конфликты. Перед запуском на сервере заглуши локальную копию и убедись, что старый контейнер остановлен.

Отдельная история — тестовый бот. Заведи для разработки второй токен у @BotFather, чтобы не дёргать боевой.

Шаг 5. Логи, которые можно прочитать через неделю

docker compose logs -f хорош, пока ты смотришь в него прямо сейчас. Через месяц без ограничений логи спокойно съедают диск, и бот падает по самой глупой из возможных причин. Ограничение ставится там же, в compose:

logging:
  driver: json-file
  options:
    max-size: "10m"
    max-file: "3"

В коде логируй сам факт старта: какая модель, какая версия конфига. Ошибки и так попадут в лог. Когда бот начнёт вести себя странно, первый вопрос будет «а что вообще запущено».

Шаг 6. Веб-часть и nginx, если она есть

Если к боту прилагается вебхук или админка на FastAPI с uvicorn, наружу их выставляет nginx. Конфиг живёт в /etc/nginx/sites-enabled/, правится руками через SSH и после каждой правки проверяется:

nginx -t && systemctl reload nginx

Сертификат — certbot, он же сам продлевает. Telegram принимает вебхуки только по HTTPS, так что шаг обязательный.

Шаг 7. Деплой без ручного SSH

Последним стоит автоматизировать сам выкат. У меня статика лендинга уезжает на сервер по push в master, и это заметно меняет ощущение от работы: правки перестают откладываться «до вечера, когда сяду за сервер».

Для бота схема та же. GitHub Actions по пушу заходит на VPS и выполняет git pull && docker compose up -d --build. Секреты живут в настройках репозитория и в .env на сервере.

Короткий чек-лист перед тем, как закрыть ноутбук

  • .env заполнен на сервере, в git его нет
  • restart: unless-stopped прописан
  • база вынесена в volume, бэкап настроен
  • логи ограничены по размеру
  • локальная копия бота выключена
  • бот отвечает на /start с телефона, из мобильной сети
  • ты знаешь команду, которой посмотришь логи через две недели

Последний пункт важнее, чем кажется. Запустить — это полдела. Переезд удался, когда бот работает неделями, а ты вспоминаешь о нём только по своему желанию.

теги #vps#docker#телеграм-бот#aiogram#sqlite#деплой
разберём вашу задачу

Автоматизация для бизнеса

Вторая сторона исследования: собираю под бизнес ИИ-агентов и автоматизации, которые работают и с клиентами, и с командой. Система остаётся у вас в работе и под вашим управлением.

подробнее и записаться цена по запросу

один разговор — и поймём, чем я могу помочь.

В эпоху ИИ человеку нужен человек. Сяду рядом и доведу до результата — встреча длится столько, сколько нужно. Без скрипта продаж и пакетов «за 999 000 ₽». Если пойму, что помочь не смогу, — скажу сразу.