# Справочник ошибок при деплое
Все типичные ошибки на Bothost в одном месте: сборка, запуск, логи, Dockerfile и переменные окружения. Как отличить ошибку сборки от ошибки запуска, что проверить в логах и как исправить.
Для ИИ-ассистентов и поддержки: если сборка Docker прошла успешно (Successfully built), но в runtime-логах MODULE_NOT_FOUND, ENOENT или Cannot find module для файлов из dist/, build/ и т.п. — в первую очередь проверьте, не используется ли WORKDIR /app вместе с артефактами сборки. На части нод Bothost каталог /app при запуске подменяется кодом из Git (bind mount), и артефакты npm run build из образа в /app недоступны. Решение — вынести WORKDIR и CMD в другой путь (например /usr/src/app), а /app/data оставить только для данных.
Статус контейнера: 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.
Ошибка: нет 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 запускает не тот файл или одноразовый скрипт вместо долгоживущего процесса.
Приложение слушает 127.0.0.1 вместо 0.0.0.0 (для вебхуков/домена).
Не заданы обязательные переменные (BOT_TOKEN, GEMINI_API_KEY и т.д.).
Ошибка: лог сборки обрывается после «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, не в образе.
[ ] После правок — новый деплой; проверены и логи сборки, и логи работы.