На компьютере бот отвечает, после деплоя на Bothost контейнер уходит в restarting или сразу exited. Ниже Python ModuleNotFoundError, отсутствующий .env, неверный главный файл и то, как отличить это от ошибок Node MODULE_NOT_FOUND.

Для людей и ИИ. Каноническая страница: https://bothost.ru/docs/works-locally-fails-on-server · Markdown: https://bothost.ru/docs/works-locally-fails-on-server.md · Индекс: https://bothost.ru/llms.txt
Отвечает на запросы: bot works locally but not on server, bot crashes after deployment, ModuleNotFoundError, No module named, ImportError, attempted relative import, can't open file, KeyError BOT_TOKEN, container restarting.
Node.js Cannot find module '/app/dist/...' и Cannot find module '/app/index.js' разобраны отдельно: справочник ошибок при деплое.

Как устроен запуск на Bothost

Контейнер — Linux. В него попадает код из Git или из архива, зависимости ставятся на сборке из requirements.txt или package.json. Локальное виртуальное окружение, пакеты из pip install «просто в систему» и файл .env с вашего диска в контейнер не копируются. Платформа передаёт токен и служебные переменные сама: BOT_TOKEN, API_TOKEN, TELEGRAM_BOT_TOKEN, для Discord DISCORD_BOT_TOKEN, плюс PORT, DATA_DIR=/app/data и при включённом домене WEBHOOK_URL. Полный список: переменные окружения. Сборка и запуск — разные логи.
Что открытьО чём говорит
Логи сборкиpip install, npm ci, ошибка Dockerfile. Пока сборка красная, процесс бота ещё не стартовал
Логи работыПервая ошибка после старта процесса: импорт, нет файла, нет переменной, синтаксис
Сообщение об успешной сборке значит только то, что образ собрался. Падение в логах работы при зелёной сборке — тема этой статьи.

Сначала статус

Пока контейнер в restarting, бот не может отвечать в Telegram, держать webhook или писать в базу. Ищите в логах работы первую строку traceback в цикле и сопоставьте её с разделами ниже. Повтор той же ошибки каждые несколько секунд — процесс стартует и сразу завершается, Docker поднимает его снова.

ModuleNotFoundError

Как выглядит

ModuleNotFoundError: No module named 'aiogram'
Варианты той же ситуации: No module named 'dotenv', No module named 'PIL', No module named 'handlers'. Сборка при этом часто успешна: pip отработал по тому requirements.txt, который был в репозитории, и пакета там не было.

Почему локально пакет есть

На компьютере библиотека стоит в venv или в пользовательском site-packages. На Bothost ставится только то, что перечислено в корневом requirements.txt (или объявлено в pyproject.toml). Команда сборки:
pip install --no-cache-dir -r requirements.txt
Имя в файле и имя в import часто различаются:
В requirements.txtВ коде
python-dotenvimport dotenv
Pillowimport PIL
python-telegram-botimport telegram
pyTelegramBotAPIimport telebot
discord.pyimport discord
Если в файле нет строки, в контейнере нет модуля, даже если на вашей машине python -c "import aiogram" проходит.

Что сделать

    • Добавьте пакет в корневой requirements.txt и зафиксируйте версию, с которой бот проверен локально:
aiogram==3.13.1
python-dotenv==1.0.1
Без версии на сборке может приехать другой мажор, и падение будет уже на ImportError внутри библиотеки, а не на No module named.
    • Задеплойте заново. Рестарт контейнера зависимости не доустанавливает: они попадают в образ только при сборке.
    • Убедитесь, что файл лежит в корне репозитория, а не только в подпапке, если бот собирается из корня.
Подробнее про форматы зависимостей Python, Java и Go: установка библиотек.

ModuleNotFoundError на свой файл

ModuleNotFoundError: No module named 'handlers'
Это уже не пакет с PyPI. Локально файл находится из-за того, что вы запускаете скрипт из папки проекта и IDE добавляет её в sys.path. В контейнере рабочий каталог /app, а пакет не является пакетом: нет запуска как модуля, или импорт написан относительно запускаемого файла.
ImportError: attempted relative import with no known parent package
появляется, когда файл с from .handlers import router запустили как скрипт (python bot.py), а не как модуль (python -m package.bot). На Bothost команда запуска — это главный файл из настроек. Либо укажите запуск модулем через свой Dockerfile (кастомный Dockerfile), либо замените относительные импорты на импорты от корня проекта, который реально есть в /app. Регистр букв на Linux важен. import Config не откроет config.py. Windows такой импорт часто прощает. Переименуйте файл и импорт в один регистр и задеплойте снова.

bot crashes after deployment

Нет переменной, которая локально приходит из .env

KeyError: 'BOT_TOKEN'
Token is invalid or not found
Локально токен берётся из .env через python-dotenv или из переменных IDE. Файл .env обычно в .gitignore, в клон на сервере он не входит. load_dotenv() молча ничего не загружает, следующая строка падает. На Bothost токен уже лежит в BOT_TOKEN. Читайте его напрямую:
import os

token = os.environ["BOT_TOKEN"].strip()
Дополнительные секреты (OPENAI_API_KEY и подобные) добавьте в разделе переменных окружения бота в панели, затем перезапустите контейнер. Коммитить их в репозиторий не нужно. Если имя в коде другое (TOKEN, TG_BOT_TOKEN), заведите в панели переменную с этим именем или поменяйте код на BOT_TOKEN.

Неверный главный файл

python: can't open file '/app/bot.py': [Errno 2] No such file or directory
В настройках бота или в CMD указан файл, которого нет в корне. Код лежит во вложенной папке (mybot/bot.py), а поле «Главный файл» пустое или содержит bot.py. Укажите путь от корня репозитория, например mybot/bot.py, и задеплойте снова. Как платформа выбирает точку входа: главный файл. Для Node та же ситуация даёт Cannot find module '/app/index.js'. Это отдельный разбор в справочнике ошибок, вместе с пропадающим dist/ при WORKDIR /app.

Синтаксис и версия Python

SyntaxError: invalid syntax
TypeError: ... unexpected keyword argument
Образ Python на платформе может отличаться от версии на компьютере. Конструкция, которая есть только в более новой версии, валит процесс на первой строке. Зафиксируйте совместимый код или соберите образ со своей версией через Dockerfile. В логе сборки видно, какой интерпретатор ставит зависимости.

Процесс сразу завершается без ошибки

В логе есть ваш print и больше ничего, статус exited или restarting. Скрипт дошёл до конца: нет start_polling, client.run, app.run или другого бесконечного цикла. Локально вы этого не замечаете, потому что следом смотрите в консоль и запускаете снова. Бот на сервере должен оставаться запущенным процессом, а не одноразовым скриптом.

bot works locally but not on server

Если процесс всё же running, а не падает, это уже не импорт. Сверьте поведение, которое на компьютере маскируется окружением:
  • токен и режим апдейтов: бот не отвечает;
  • webhook на localhost локально не проверяется, на сервере Telegram ходит на публичный HTTPS: ошибки webhook;
  • база в папке проекта жива на диске компьютера и пустая в новом контейнере: SQLite пропала;
  • исходящий вызов к нейросети таймаутится из-за региона IP ноды: в справочнике ошибок раздел про DeepSeek, Gemini, OpenAI и Claude.

Порядок в логах

    • Логи сборки зелёные, в них есть pip install по вашему requirements.txt.
    • Логи работы: первая строка traceback совпадает с одним разделом выше.
    • После правки файла зависимостей или главного файла сделан новый деплой, а не только рестарт.
    • Статус держится running, в логе есть строка старта polling или HTTP-сервера.

См. также

В логе другая ошибка? Пришлите первую строку traceback в поддержку: @bothostru.