Files
vidconf/backend/Dockerfile
Max Ronzhin 6d65b620fe perf(backend): явный пул соединений БД и несколько воркеров uvicorn
Пул создавался с дефолтом SQLAlchemy (5 + 10) и под нагрузкой выгребался
за секунды. Теперь параметры заданы явно и вынесены в настройки:
DB_POOL_SIZE=10, DB_MAX_OVERFLOW=10, DB_POOL_TIMEOUT=10. Таймаут снижен с
дефолтных 30 секунд намеренно — пусть запрос падает быстро и показывает
проблему, а не висит полминуты.

Backend запускался одним процессом uvicorn: любой блокирующий вызов
останавливал и параллельные запросы, и WS-чат всех участников. Добавлен
UVICORN_WORKERS с дефолтом 2 — не по числу ядер, потому что на
четырёхъядерном сервере ядра делятся с LiveKit, а медиа важнее API.

Бюджет соединений считается на весь инстанс: каждый воркер держит свой
пул, поэтому UVICORN_WORKERS × (DB_POOL_SIZE + DB_MAX_OVERFLOW) должно
оставаться заметно ниже max_connections у Postgres.

Многопроцессность безопасна: бутстрап настроек в lifespan идемпотентен
(INSERT ... ON CONFLICT DO NOTHING), а WS-чат разносит сообщения через
Redis pub/sub и состояния в памяти процесса не держит.
2026-07-28 19:00:05 +03:00

50 lines
2.4 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.
CMD ["sh", "-c", \
"exec uv run uvicorn main:create_app --factory --host 0.0.0.0 --port 8000 --workers ${UVICORN_WORKERS:-2}"]