Как правильно экспортировать зависимости Python в Docker

Как правильно экспортировать зависимости Python в Docker

Введение

Экспортировать зависимости python в докер — задача, кажущаяся тривиальной, но часто приводящая к раздуванию образов и медленным сборкам. Классический подход с копированием requirements.txt игнорирует возможности кэширования слоёв. Разберём проверенные методы оптимизации процесса.

Проблемы классического подхода

Типичный Dockerfile содержит уязвимую структуру:

COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

Любое изменение исходного кода сбрасывает кэш команды RUN pip install. Образы также накапливают лишние утилиты сборки, что критично для финальных стадий развёртывания.

Оптимизация через BuildKit

Используйте двухэтапный процесс. Активация BuildKit через DOCKER_BUILDKIT=1 открывает доступ к продвинутому кэшированию.

FROM python:3.11-slim AS builder
RUN pip install --no-cache-dir --prefix=/install uv
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --target=/install

FROM python:3.11-slim
COPY --from=builder /install /usr/local
COPY . /app
WORKDIR /app
CMD ["python", "main.py"]

Инструмент uv ускоряет установку в десятки раз благодаря параллельной загрузке. Флаг —frozen жёстко фиксирует версии, исключая дрейф зависимостей.

Сравнение методов

Метод Время сборки Размер Кэш
pip + requirements.txt Высокое Среднее Низкое
uv + pyproject.toml Низкое Минимальное Высокое
Мультистейдж Оптимальное Минимальное Максимальное

Практические рекомендации

Разделяйте установку пакетов и копирование кода. Используйте slim-образы для снижения поверхности атаки. Настройте BuildKit в CI/CD. Избегайте установки build-essential без крайней необходимости.

Вопрос-ответ (FAQ)

Зачем использовать двухэтапную сборку?

Она отделяет среду сборки от выполнения. В финальный образ попадают только бинарники, что снижает размер и исключает лишние утилиты.

Как кэшировать зависимости при изменении кода?

Размещайте RUN pip install или uv sync до COPY . .. Кэш переиспользуется, если файлы версий не изменены.

Можно ли использовать requirements.txt с uv?

Да, но не рекомендуется. uv требует pyproject.toml и uv.lock для детерминированных сборок. requirements.txt не фиксирует транзитивные зависимости точно.

Comments are closed.