Скидка 5% при первом запуске GPU по промокоду Активировать скидку

VPS с самостоятельным администрированием

Сохранение истории Telegram-бота после перезапуска

Перезапуск не должен незаметно обнулять разговор или повторять последний платный запрос. Пример Telegram-бота хранит в SQLite три вида состояния: недавнюю переписку, курсор обновлений и дневной счётчик попыток. Они находятся в Docker volume bot-data, а не во временной файловой системе контейнера.

Что именно сохраняется

Состояние Зачем нужно Что происходит при потере
Последние сообщения пользователя и модели Контекст следующего запроса Разговор продолжается без прежнего контекста
Курсор обновлений Telegram Учёт уже принятых обновлений Ещё ожидающие обновления могут обработаться повторно
Дневной счётчик Общий лимит запросов Новый счётчик допускает дополнительные попытки

По умолчанию сохраняются четыре завершённые пары «вопрос–ответ» на разрешённого пользователя. HISTORY_TURNS=0 отключает историю разговора, но не курсор и дневной лимит. Вход ограничен 2000 символами по умолчанию; ответ обрезается перед отправкой и сохранением. Это ограничения приложения, а не точный расчёт контекста токенизатором выбранной модели.

История хранится открытым текстом и содержит сообщения и Telegram ID. Защищайте её как пользовательские данные. При следующем запросе сохранённая история отправляется модели. Сообщения внутри Telegram существуют отдельно: очистка SQLite не удаляет их и не очищает записи на стороне inference-провайдера.

Контейнер, volume и VPS живут по-разному

Compose подключает bot-data:/data, а DB_PATH по умолчанию равен /data/bot.sqlite. Эти настройки должны согласовываться. База вне подключённого каталога не получает постоянное хранение автоматически. Контейнер работает с read-only корнем и непривилегированным пользователем. Выдавать всем права записи вместо исправления пути не нужно.

Из исходного каталога развёртывания:

docker compose ps
docker volume ls
docker compose exec -T bot python - <<'PYCODE'
from pathlib import Path
p = Path('/data/bot.sqlite')
print({'database_exists': p.is_file(), 'bytes': p.stat().st_size if p.is_file() else 0})
PYCODE

Команды показывают наличие и размер базы, не содержимое переписки. -T позволяет передать heredoc без интерактивного терминала. Пустая новая база тоже может выглядеть исправной: дополнительно проверьте в Telegram сохранение безобидного факта из разговора.

restart, пересборка контейнера и обычный docker compose down сохраняют named volume. down -v его удаляет. При смене имени Compose-проекта или каталога может подключиться другой volume. Сохраняйте идентичность проекта при обновлениях и не подставляйте случайный похожий volume в поисках истории.

Почему после аварии вопрос может остаться без ответа

Бот фиксирует курсор и счётчик до обращения к inference. Если он упадёт сразу после записи, вопрос может потеряться без вызова модели. Если сбой произойдёт после генерации, но до отправки в Telegram, списание возможно без доставленного ответа. При следующем старте платная попытка автоматически не повторяется.

Это политика «не более одной попытки» при обычной работе с сохранным состоянием, а не гарантия доставки ровно один раз. Восстановление старого бэкапа откатывает курсор и счётчик. Вторая копия с тем же токеном и другой базой тоже обходит локальную координацию. Эти случаи требуют отдельных действий: см. бэкап и перенос.

Очистка контекста и отзыв доступа

Команда /reset удаляет сохранённый контекст разрешённого пользователя, не сбрасывая общий бюджет. Чтобы отозвать доступ, удалите ID из ALLOWED_TELEGRAM_USER_IDS и пересоздайте контейнер. При старте он удаляет историю пользователей, которых больше нет в списке. Это не полное удаление данных из Telegram и систем inference-провайдера; старые копии базы также могут содержать прежнюю переписку.

Volume на том же VPS переживает замену контейнера, но не уничтожение сервера. Нужна копия вне VPS и отдельное защищённое хранение .env. Далее: резервное копирование и обновления и мониторинг. Источник: Docker volumes.

Тарифы из текущего каталога

Сейчас не удалось загрузить планы. Смотрите актуальные тарифы на странице цен.