Files
vidconf/backend/Dockerfile
Max Ronzhin 7a5e9d2d8a
Some checks failed
CI / backend (push) Has been cancelled
CI / frontend (push) Has been cancelled
perf(deploy): не пересобирать окружение uv в рантайме контейнеров
Образ собран с `uv sync --frozen --no-dev`, но `uv run` перед каждым запуском
заново синхронизирует venv и подтягивает dev-группу. В логах старта
vidconf-backend-1 и vidconf-worker-1 на проде это видно как «Downloading ruff /
mypy / pygments» и «Installed 12 packages». Хуже всего healthcheck'и: они
выполняют ту же синхронизацию каждые 15 секунд всю жизнь контейнера.

Проверено на локально собранном образе, одна и та же команда:

  uv run             — качает 12 пакетов, venv 456 → 574 МБ
  uv run --no-sync   — не качает ничего, venv остаётся 456 МБ

Флаг добавлен во все вызовы в прод-путях: CMD образа, command/entrypoint/
healthcheck всех сервисов compose, миграции и seed в install.sh, те же команды
в docs/deploy. Локальная разработка (dev-setup.md, backend/README.md, CI) не
затронута — там dev-зависимости нужны. Заодно убрано устаревшее объяснение
ретрая `up -d --wait`: первый старт больше не синхронизирует окружение.

Версия uv в образе — 0.11.33, `--no-sync` поддерживается.
2026-07-28 23:25:56 +03:00

57 lines
3.0 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
FROM python:3.12-slim AS base
# uv binary, pinned via digest-less tag (see astral-sh/uv releases)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /usr/local/bin/
WORKDIR /app
ENV UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
PYTHONUNBUFFERED=1
# Экстра-группа `gpu` (ADR-004: cuBLAS/cuDNN9 для FasterWhisperGPU,
# `core/plugins/faster_whisper.py`) — ставится ТОЛЬКО в GPU-образе воркера
# транскрибации (deploy/docker-compose.yml, сервис `worker-transcriber-gpu`,
# `build.args.WITH_GPU_EXTRA: "true"`, профиль `transcribe-gpu`); базовый
# CPU-образ backend/worker/worker-transcriber собирается с дефолтом "false"
# — не тянет нативные CUDA-библиотеки туда, где GPU нет.
ARG WITH_GPU_EXTRA=false
# Install dependencies first (better layer caching), then copy source.
COPY pyproject.toml uv.lock ./
RUN if [ "$WITH_GPU_EXTRA" = "true" ]; then \
uv sync --frozen --no-dev --no-install-project --extra gpu; \
else \
uv sync --frozen --no-dev --no-install-project; \
fi
COPY . .
RUN if [ "$WITH_GPU_EXTRA" = "true" ]; then \
uv sync --frozen --no-dev --extra gpu; \
else \
uv sync --frozen --no-dev; \
fi
EXPOSE 8000
HEALTHCHECK --interval=10s --timeout=5s --retries=10 --start-period=15s \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')" || exit 1
# Число воркеров — из окружения (`UVICORN_WORKERS`, см. docker-compose.yml).
# Один процесс означает, что любой блокирующий вызов в обработчике
# останавливает весь event loop: параллельные запросы и WS-чат всех
# участников встают в очередь. Дефолт 2, а не «по числу ядер»: медиа
# важнее API, и на 4-ядерном сервере LiveKit в пике забирает 1.6 ядра.
#
# `sh -c` нужен ради подстановки переменной (exec-форма её не делает),
# `exec` — чтобы uvicorn получил PID 1 и корректно принимал SIGTERM.
#
# `--no-sync`: окружение уже собрано выше (`uv sync --frozen --no-dev`), и
# пересобирать его в рантайме незачем. Без флага `uv run` перед каждым
# запуском заново синхронизирует venv И ПОДТЯГИВАЕТ dev-группу (ruff, mypy,
# pytest — ~30 МБ загрузок на каждый старт контейнера, dev-инструменты в
# проде и раздутый venv). То же касается healthcheck'ов в
# deploy/docker-compose.yml, которые дёргают `uv run` каждые 15 секунд.
CMD ["sh", "-c", \
"exec uv run --no-sync uvicorn main:create_app --factory --host 0.0.0.0 --port 8000 --workers ${UVICORN_WORKERS:-2}"]