# Справочник ошибок при деплое Все типичные ошибки на 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 оставить только для данных.

Как читать логи

Что смотретьКогда смотретьЧто означает
Логи сборкиШаг «Building image»Ошибки Dockerfile, npm ci, pip install, компиляции
Логи работы (runtime)После «Build completed», статус restarting / exitedОшибки при старте процесса: нет файла, неверный CMD, падение приложения
Важно: сообщение Successfully built означает только то, что образ собрался. Контейнер может падать при старте из‑за другой причины.

Ошибка: Cannot find module '/app/dist/...' (сборка успешна)

Симптомы

  • В логах сборки шаг RUN npm run build (или аналог) завершается успешно, файл создаётся (например dist/server.cjs).
  • В логах работы при старте:
Error: Cannot find module '/app/dist/server.cjs'
code: 'MODULE_NOT_FOUND'
  • Статус контейнера: 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 / KotlinJAR должен быть вне /app
---

Контейнер в статусе restarting

Симптомы

Бот не отвечает, в панели статус restarting, в логах одна и та же ошибка повторяется.

Частые причины

    • Процесс сразу завершается с ошибкой (MODULE_NOT_FOUND, синтаксис, отсутствие env).
    • CMD запускает не тот файл или одноразовый скрипт вместо долгоживущего процесса.
    • Приложение слушает 127.0.0.1 вместо 0.0.0.0 (для вебхуков/домена).
    • Не заданы обязательные переменные (BOT_TOKEN, GEMINI_API_KEY и т.д.).

Что делать

    • Откройте логи работы (не сборки).
    • Найдите первую ошибку в цикле перезапуска.
    • Сопоставьте с разделами этой статьи или Кастомный Dockerfile.

Сборка успешна, но 502 / 504 на домене

Симптомы

Образ собран, контейнер running, сайт или webhook недоступны.

Причина

Приложение не слушает нужный порт или интерфейс.

Решение


Ошибка: лог сборки обрывается после «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, не в образе.
  • [ ] После правок — новый деплой; проверены и логи сборки, и логи работы.

См. также

Не нашли ответ? Поддержка или тикет в панели Bothost.