# Справочник ошибок при деплое
Все типичные ошибки на Bothost в одном месте: сборка, запуск, логи, Dockerfile и переменные окружения. Как отличить ошибку сборки от ошибки запуска, что проверить в логах и как исправить.
Для ИИ-ассистентов и поддержки:
1. Если сборка успешна, но runtime MODULE_NOT_FOUND для dist/, build/ и т.п. — проверьте WORKDIR /app + bind mount: артефакты сборки в /app недоступны. Решение — WORKDIR /usr/src/app, данные оставить в /app/data.
2. Если ошибка Cannot find module '/app/index.js' (или другой entrypoint в корне/app), а в репозитории код лежит во вложенной папке — это не bind mount. В корневом package.json указан index.js, которого в корне нет. Укажите путь к реальному файлу (main file / scripts.start) или вынесите код в корень.
3. Если MODULE_NOT_FOUND для пути вроде /app/src/data/... (или любой вложенной…/data/…), а файл есть в Git — на нодах с bind mount раньше агент пропускал все папки data при копировании кода. Нужен редеплой после фикса агента (игнорируется только корневой /app/data).
4. Индекс документации для LLM: https://bothost.ru/llms.txt · полный текст: https://bothost.ru/llms-full.txt · эта статья в Markdown: https://bothost.ru/docs/common-errors.md
Статус контейнера: restarting (циклический перезапуск).
Причина
На Bothost при деплое с кастомным Dockerfile возможна такая схема:
При сборке образа в WORKDIR /app выполняется npm run build → в образе появляется /app/dist/....
При запуске контейнера на части серверов каталог /app монтируется с хоста: туда попадает исходный код из Git, без папки dist/ (её обычно нет в репозитории и в .gitignore).
Команда CMD ["node", "dist/server.cjs"] ищет файл в примонтированном/app, а не в слое образа → MODULE_NOT_FOUND.
Типичный кейс: Node.js/TypeScript проект с esbuild/tsc, WORKDIR /app, DATA_DIR=/app/data, как в Negodiay-Bot.
Платформа отдельно восстанавливает из образа на хост node_modules (для Node.js), но не каталоги вроде dist/, build/, .next/ — их нужно либо не класть в /app, либо собирать при каждом старте.
Решение
Перенесите код приложения и артефакты сборки вне/app. Каталог /app/data оставьте для персистентных данных (БД, загрузки) — он как раз предназначен для volume.
Было (проблемный вариант):
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build
ENV DATA_DIR=/app/data
RUN mkdir -p /app/data && chmod 777 /app/data
CMD ["node", "dist/server.cjs"]
Стало (рекомендуется):
FROM node:20-alpine
WORKDIR /usr/src/app
COPY . .
RUN npm ci
RUN npm run build
ENV NODE_ENV=production
ENV DATA_DIR=/app/data
RUN mkdir -p /app/data && chmod 777 /app/data
EXPOSE 3000
CMD ["node", "dist/server.cjs"]
Пояснения:
WORKDIR /usr/src/app — здесь лежат исходники и dist/ из образа; bind mount на /app их не затирает.
CMD выполняется относительно WORKDIR, путь dist/server.cjs корректен.
DATA_DIR=/app/data — данные по-прежнему в volume Bothost (хранение БД).
Дополнительно проверить
В коде пути к данным берутся из process.env.DATA_DIR или path.join('/app/data', ...), а не из __dirname относительно старого /app.
Папка dist/ в .gitignore — это нормально; на Bothost она должна жить в образе (или вне /app), а не в Git.
Альтернативы
Сборка при старте в entrypoint.sh (медленнее, но всё в /app): npm run build && node dist/server.cjs.
Multi-stage Dockerfile: финальный COPY --from=builder артефактов в /usr/local/bin или другой путь вне /app.
Ошибка: Cannot find module '/app/src/data/...' (файл есть в Git)
Симптомы
Сборка образа успешна.
В логах работы: ERR_MODULE_NOT_FOUND / Cannot find module '/app/src/data/templates.js' (или другой файл во вложенной папке data).
В GitHub файл на месте; в файл-менеджере бота папки src/data/ может не быть.
Причина
На нодах с bind mount агент копирует код репозитория на хост и не перезаписывает корневой /app/data (персистентный volume). Раньше использовался ignore_patterns('data'), который пропускал любую папку с именем data на любой глубине — в том числе исходники src/data/, lib/data/ и т.п.
Это не кейс с dist/ и не неверный entrypoint.
Решение
Обновить агент на ноде (фикс: игнорируется только корневой data/).
Сделать новый деплой бота (одного рестарта мало — код на хосте нужно перекопировать).
Временный обходной путь без обновления агента: переименовать вложенную папку (например src/data → src/datasets) и поправить импорты.
Ошибка: Cannot find module '/app/index.js' (код во вложенной папке)
Симптомы
Сборка образа проходит успешно (Successfully built).
В файл-менеджере бота в корне видны package.json и подпапка с кодом, но нетindex.js в корне /app.
Как отличить от ошибки с dist/
Критерий
Этот кейс
Кейс с dist/ выше
Путь в ошибке
/app/index.js, /app/main.js и т.п. (исходник)
/app/dist/..., /app/build/...
Файл в Git
Нет в корне репозитория
Обычно есть после npm run build в образе, но нет в Git
Причина
Неверный entrypoint / nested-структура
Bind mount затирает артефакты сборки
Фикс
Указать правильный путь к файлу
WORKDIR вне /app
Причина
Агент Bothost (и автогенерация Dockerfile) читает корневойpackage.json и запускает то, что указано в main / scripts.start (часто node index.js).
Если репозиторий устроен так:
repo/
├── package.json ← "main": "index.js", "start": "node index.js"
├── README.md
└── my-bot/ ← весь код здесь
├── index.js
├── package.json
└── ...
то в корне нетindex.js, а контейнер всё равно стартует с CMD ["node", "index.js"] → Cannot find module '/app/index.js'.
Типичный пример: FuF1iK/botds — код в discord-html-watcher/, а корневой package.json ссылается на несуществующий корневой index.js.
Это не связано с bind mount и WORKDIR: файла просто никогда не было по пути, который указан в команде запуска.
Решение
Выберите один из вариантов.
1. Указать main file при деплое (быстрее всего)
В форме создания бота откройте «Дополнительные настройки» и в поле «Главный файл (точка входа)» укажите путь от корня репозитория, например discord-html-watcher/index.js (или subdir/index.js / bot/main.js для своего репо).
Пример: для репозитория FuF1iK/botds в поле указан discord-html-watcher/index.js.
Полная инструкция по полю и автодетекту: Главный файл (точка входа).
repo/
├── index.js ← точка входа в корне
├── package.json ← "main": "index.js", "start": "node index.js"
└── ...
Тогда стандартный автодетект Bothost (node index.js) сработает без поля «Главный файл» и без правок путей. После переноса сделайте новый деплой.
Дополнительно проверить
В корневом package.json поля main и scripts.start указывают на файл, который реально есть в репозитории (проверьте пути в GitHub).
Если в корне «лишний» package.json (копия или заглушка), а рабочий проект только во вложенной папке — либо поправьте пути, либо уберите корневой файл и укажите main file вручную.
После смены entrypoint нужен новый деплой, одного рестарта контейнера недостаточно, если образ/команда запуска уже зафиксированы со старым путём.
Ошибка: нет node_modules при кастомном Dockerfile (Node.js)
Симптомы
Error: Cannot find module 'express' (или другой пакет из package.json).
Сборка образа прошла, зависимости ставились в RUN npm ci.
Причина
Та же модель, что и с dist/: при монтировании /app с хоста локальный node_modules из образа в /app не виден. Bothost пытается скопировать node_modules из образа на хост при деплое; если структура проекта нестандартная (WORKDIR не /app при сборке), копирование может не совпасть с путём запуска.
Решение
Используйте WORKDIR вне /app для запуска или убедитесь, что npm ci в Dockerfile и CMD согласованы с тем, откуда реально стартует node.
Не полагайтесь на node_modules в Git — только в образе/на хосте после деплоя.
Ошибка: Go/Rust/Java бот — сборка успешна, контейнер сразу падает, логов нет
Симптомы
Все шаги docker build завершились успешно, образ создан.
Сразу после ==> Build completed бот в статусе error / failed.
В логах сборки нет вывода от самого приложения — только сообщение агента
«Контейнер упал сразу после запуска».
Runtime-логи (docker logs) пусты или содержат:
exec /app/bot: no such file or directory
В файл-менеджере бота видны исходники (main.go, go.mod, …), но нет бинарника.
Причина
На Bothost каталог /app при запуске контейнера монтируется с исходниками бота из Git (bind mount).
Это нужно для файлового менеджера и горячего обновления кода. Для интерпретируемых языков
(Python, Node.js) всё работает: исходник и есть запускаемый файл. Для компилируемых языков
(Go, Rust, Java) бинарник/JAR живёт в слое образа, а bind mount его скрывает.
/app/bot ← скрыт bind mount'ом
/app/server ← тоже скрыт
/app/bin/server ← тоже скрыт (весь /app перекрыт)
Решение
Положите скомпилированный артефакт вне /app — например в /usr/local/bin/.
Было (падает):
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN go build -o /app/bot .
FROM alpine:3.20
WORKDIR /app
COPY --from=builder /app/bot . # ← скрыт bind mount'ом
CMD ["./bot"] # ← не найден
Стало (работает):
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN go build -o /usr/local/bin/bot .
FROM alpine:3.20
WORKDIR /app
COPY --from=builder /usr/local/bin/bot /usr/local/bin/bot # ← вне /app
RUN mkdir -p /app/data && chmod 777 /app/data
CMD ["/usr/local/bin/bot"] # ← работает
Данные (БД, файлы) по-прежнему хранятся в /app/data — bind mount их видит
и сохраняет между деплоями.
Примечание: кастомный Dockerfile vs автогенерация
Если у вас в репозитории нет своего Dockerfile, агент Bothost генерирует его
автоматически — и уже кладёт бинарник в /usr/local/bin/ корректно.
Проблема возникает только при использовании кастомного Dockerfile из репозитория
со старой схемой (COPY ... /app/).
Самый быстрый способ исправить: снять галку «Использовать Dockerfile из репозитория»
при деплое, тогда агент сгенерирует правильный вариант сам.
Совместимость языков с bind mount на /app
Язык
Работает без изменений
Комментарий
Python
✅
Исходник запускается напрямую
Node.js
✅
То же (артефакты dist/ — отдельный кейс выше)
PHP
✅
Исходник запускается напрямую
Go
❌
Бинарник должен быть в /usr/local/bin/
Rust
❌
То же
Java / Kotlin
❌
JAR должен быть вне /app
---
Контейнер в статусе restarting
Симптомы
Бот не отвечает, в панели статус restarting, в логах одна и та же ошибка повторяется.
Частые причины
Процесс сразу завершается с ошибкой (MODULE_NOT_FOUND, синтаксис, отсутствие env).
CMD запускает не тот файл или одноразовый скрипт вместо долгоживущего процесса (в т.ч. код во вложенной папке — см. раздел про /app/index.js выше).
Приложение слушает 127.0.0.1 вместо 0.0.0.0 (для вебхуков/домена).
Не заданы обязательные переменные (BOT_TOKEN, GEMINI_API_KEY и т.д.).
Не работает DeepSeek / Gemini / OpenAI / Claude (ошибки API, timeout, geo)
Симптомы
Бот запущен, но запросы к нейросетям и зарубежным API падают: timeout, connection error, geo/region blocked, «хостинг блокирует исходящие запросы».
Причина
Bothost не блокирует исходящий трафик. У части нод IP определяется как российский, и внешний API (DeepSeek, Gemini, OpenAI, Claude и др.) отклоняет запросы.
Решение
В профиле включите «Зарубежный IP для API и нейросетей».
Задеплойте бота заново — существующие боты сами не переезжают на ноду с зарубежным IP.
Ошибка: лог сборки обрывается после «Cloning into...»
Симптомы
В логах сборки видно только:
==> Cloning https://github.com/...
Cloning into '...'...
После этого поток обрывается, статус бота переходит в failed.
Никакого сообщения об ошибке не отображается.
Причина
Клонирование прошло успешно, но на следующем шаге чтения Dockerfile произошла ошибка. Чаще всего — Dockerfile сохранён в кодировке, отличной от UTF-8 (например, Windows-1251). Агент не смог прочитать файл и завершился без вывода в лог.
Решение
Пересохраните Dockerfile в кодировке UTF-8 (в VS Code: строка состояния снизу → кликнуть на кодировку → «Save with Encoding» → UTF-8).
Уберите кириллические комментарии из Dockerfile или переведите их на английский.
Запустите деплой повторно.
Проверка кодировки
file Dockerfile
# OK: ASCII text или UTF-8 Unicode text
# Плохо: ISO-8859, windows-1251, UTF-8 Unicode (with BOM)
Ошибки только в логах сборки
Сообщение
Возможная причина
npm ci failed
Нет package-lock.json, несовместимые версии Node
go build failed
Неверный модуль, CGO, отсутствие файлов в COPY
pip install failed
Ошибка в requirements.txt, нужны системные пакеты (apk/apt в Dockerfile)
COPY failed
Файл в .dockerignore, пустой контекст
Исправляйте Dockerfile и зависимости; runtime-логи здесь не помогут, пока образ не соберётся.
Чеклист для кастомного Dockerfile (Node.js + сборка)
[ ] WORKDIR для кода и dist/не/app (например /usr/src/app).
[ ] Данные и БД — в /app/data или через DATA_DIR.
[ ] CMD указывает на файл, который реально появляется после npm run build.
[ ] Порт из process.env.PORT, хост 0.0.0.0 (если есть HTTP).
[ ] Секреты — в переменных окружения Bothost, не в образе.
[ ] После правок — новый деплой; проверены и логи сборки, и логи работы.