Кастомный Dockerfile на Bothost

Эта статья для случаев, когда стандартной автонастройки недостаточно и вы хотите полностью контролировать сборку и запуск контейнера.

Когда нужен кастомный Dockerfile

Используйте свой Dockerfile, если вам нужно:
  • установить системные пакеты (apt, apk) или нестандартные зависимости;
  • делать многоэтапную сборку (build stage + runtime stage);
  • явно контролировать команду запуска (CMD/ENTRYPOINT);
  • запускать веб-приложение вместе с ботом на конкретном порту;
  • использовать собственную структуру проекта, которую автоопределение не покрывает.
Если ваш проект простой (например, Python-бот с requirements.txt), чаще всего достаточно стандартного сценария деплоя без кастомного Dockerfile.

Базовые требования Bothost

Чтобы контейнер корректно работал с доменом/webhook на платформе:
  • приложение должно слушать 0.0.0.0, а не 127.0.0.1;
  • порт должен браться из переменной окружения PORT;
  • в настройках бота внутренний порт должен совпадать с портом, который реально слушает приложение;
  • после изменения порта/домена нужен повторный деплой.
Для веб-сервисов (FastAPI, Express и т.д.) это критично: иначе получите 502/504 даже при успешной сборке.

Минимальный шаблон для Python (бот + веб endpoint)

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

# Приложение должно читать PORT из env и слушать 0.0.0.0
CMD ["python", "main.py"]

Минимальный шаблон для Node.js

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --omit=dev

COPY . .

# Приложение должно читать PORT из env и слушать 0.0.0.0
CMD ["node", "index.js"]

Минимальный шаблон для Go (multi-stage)

FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/bot .

FROM alpine:3.20
RUN apk --no-cache add ca-certificates
WORKDIR /app
COPY --from=builder /app/bot .
CMD ["./bot"]

Типовые ошибки

  • Приложение слушает localhost вместо 0.0.0.0.
  • Порт захардкожен в коде, а не берётся из PORT.
  • CMD запускает не тот файл/бинарник.
  • Нужные файлы не копируются в образ (COPY неполный).
  • Сборка успешна, но процесс сразу падает при старте (смотрите runtime-логи, а не только build-логи).

Чеклист перед деплоем

  • Dockerfile лежит в корне репозитория.
  • Команда запуска стартует долгоживущий процесс (а не одноразовый скрипт).
  • Для веб-приложения есть обработчик health (или понятный endpoint для проверки).
  • Сервис поднимается локально с переменной PORT:
PORT=8080 docker run --rm -p 8080:8080 <image>
  • После пуша выполнен деплой и проверены:
- логи сборки, - логи запуска, - доступность домена/вебхука.

См. также