Как задеплоить бота, что делать с приватным репозиторием и что значит каждая ошибка, которую может показать панель.
Нужны три вещи: публичный или приватный GitHub-репозиторий с уже написанным ботом (Python или Node.js), токен бота от @BotFather (для MAX — см. ниже) и, если репозиторий приватный, токен доступа к нему. В форме «Новый бот» это всё — ссылка на репозиторий, при необходимости токен доступа, ветка (по умолчанию main), команда запуска (можно оставить пустым — определим сами) и токен бота.
Экосистема определяется по файлу в корне репозитория: requirements.txt → Python,package.json → Node.js. Если не нашли ни то, ни другое — деплой падает на этом шаге с понятной ошибкой (см. раздел про ошибки ниже).
Команда запуска по умолчанию для Python — python плюс главный файл из корня: main.py, bot.py, app.py или единственный .py-файл; для Node.js — npm start, если в package.json есть scripts.start, иначе node плюс значение поля main, а если и того нет — node index.js.
Бот для MAX деплоится так же, как Telegram-бот. Создать бота в MAX могут организации, ИП и самозанятые: после модерации токен появляется в карточке бота на business.max.ru. Его и вставляйте в поле «Токен бота».
Бот должен получать сообщения через long-polling — вебхуки пока не поддерживаются. Мы передаём токен в переменной BOT_TOKEN, а библиотека maxapi по умолчанию ищет MAX_BOT_TOKEN, поэтому передайте токен явно:
# requirements.txt
maxapi
# bot.py
import asyncio, os
from maxapi import Bot, Dispatcher
bot = Bot(token=os.getenv("BOT_TOKEN"))
dp = Dispatcher()
# ... ваши обработчики ...
asyncio.run(dp.start_polling(bot))Та же ссылка вида https://github.com/владелец/репо, просто дополнительно нужен токен доступа.
Токен используется только на момент клонирования и нигде не сохраняется в открытом виде — хранится зашифрованным, как и токен бота. В коде или образе собранного бота его не остаётся. Поменять токен или добавить его к уже существующему боту можно на странице бота, в блоке «Доступ к приватному репозиторию» — это пересоберёт бота с новым токеном.
Частая причина ошибки доступа — у токена не хватает прав. GitHub в этом случае отвечает Write access to repository not granted, хотя речь идёт о чтении: убедитесь, что Contents действительно выставлен в Read-only, а не оставлен на «No access» по умолчанию.
На странице бота можно добавить любые переменные окружения — они передаются в контейнер при каждой сборке. Значения хранятся зашифрованными и после сохранения не показываются обратно, только пометка «задано». Токен бота (BOT_TOKEN) — такая же переменная, просто заводится сразу при создании.
Пробный период — 30 дней с момента первого успешного запуска, все функции включены без урезаний. Он один на аккаунт: удаление и пересоздание бота его не перезапускает. За 7, 3 и 1 день до конца придёт напоминание, оплатить можно заранее прямо на странице бота — оплаченные дни добавятся после пробного периода. Тем, кто зарегистрировался до появления пробного периода, первый бот остаётся бесплатным без срока. Мест ограниченное количество — если свободных нет, форма деплоя предложит оставить контакт.
/data: выше 256 МБ придёт предупреждение, на 1 ГБ бот остановитсяВебхуки пока не поддерживаются — у контейнера бота нет публичного адреса, только исходящие long-polling запросы к Telegram или MAX. Очень нужны — напишите в поддержку.
Контейнер бота: без доступа к хосту и приватным сетям, без привилегий (--cap-drop ALL), файловая система на чтение (кроме /data и /tmp). Это не настройка «на выбор» — так устроено всегда, для всех ботов.
Токен бота и токен доступа к репозиторию хранятся зашифрованными и нигде не показываются обратно в интерфейсе — видно только «задано». Код публичного репозитория и так открыт на GitHub; приватный клонируется только на время сборки и в образе бота не остаётся.
Ссылка должна быть вида https://github.com/...URL не распознан. Только HTTPS-ссылка на GitHub, без .git в конце не обязательно, SSH-ссылки (git@github.com:...) не поддерживаются. Приватный репозиторий — та же форма ссылки, доступ даёт отдельный токен.
Бот «X» уже существуетТакой идентификатор уже занят — возможно, вашим же старым ботом. Выберите другой id или удалите существующий бот.
На бесплатном тарифе — один бот на аккаунтУдалите текущего бота на странице бота (кнопка «Удалить»), чтобы задеплоить другого — свободный слот освободится сразу.
Свободных мест пока нетНода заполнена — лимит ограничен мощностью сервера, не количеством желающих. Оставьте контакт в форме — напишем, когда освободится.
Не удалось склонировать репозиторийПроверьте ссылку и ветку. Для приватного репозитория — скорее всего не хватает прав у токена: нужен именно Contents: Read-only на этот репозиторий (см. раздел выше).
Репозиторий слишком большойПосле клонирования репозиторий весит больше 200 МБ. Это ограничение на размер исходников, не на готовый образ.
Не найден ни requirements.txt, ни package.jsonВ корне репозитория (не во вложенной папке) должен лежать один из этих файлов — так определяется, Python это или Node.js. Если в корне есть .py-файлы, в ошибке будет готовый список строк для requirements.txt — по импортам в вашем коде.
Не удалось установить зависимостиОшибка в самом файле зависимостей — опечатка в названии пакета, несуществующая версия и т.п. Полный текст ошибки pip/npm — в логе сборки прямо над этой строкой.
Бот упал сразу после запускаКонтейнер собрался, но процесс внутри завершился за первые 20 секунд. Частые причины мы распознаём и пишем прямо в ошибке: не тот файл запуска, библиотека не указана в requirements.txt, запись файлов вне /data, неверный BOT_TOKEN или бот уже запущен где-то ещё. В остальных случаях трейс — в логе прямо над этой строкой.
Тот же токен бота уже где-то опрашивает Telegram — другой из ваших ботов, старый контейнер, локальный запуск на своей машине. Telegram отдаёт обновления только одному процессу разом. Остановите дубликат (или смените токен одному из ботов) — конфликт снимается сам, как только дубликата не остаётся.
Супервизор перезапускает упавший процесс с растущей паузой; если это происходит 5 раз за 10 минут — останавливает бота и присылает одно уведомление (если привязаны алерты), а не спамит бесконечно. Исправьте код по логам и передеплойте, либо просто нажмите «Запустить» ещё раз, если проблема была разовой.
/data бота занимает больше 256 МБ. Бот продолжает работать, но данные стоит почистить: на 1 ГБ бот остановится, чтобы не заполнить общий диск сервера.
Пробный период — 30 дней, без урезаний. Дальше — 299 ₽ за бота в месяц, на 6 и 12 месяцев дешевле (до −25%), от 3 ботов ещё скидка; без автосписания: оплата на странице бота, места для новых ботов — на странице Тарифы.