Перейти к содержимому
Главная страница » Сборка Python проекта с uv и Docker

Сборка Python проекта с uv и Docker

Best practice Dockerfile for Python with uv

Ниже приведён пример Dockerfile, который мы используем и рекомендуем при создании образов Docker для приложений Python, использующих uv в качестве менеджера пакетов.

FROM python:3.12-slim-bookworm AS base
FROM base AS builder
COPY --from=ghcr.io/astral-sh/uv:0.4.9 /uv /bin/uv
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
WORKDIR /app
COPY uv.lock pyproject.toml /app/
RUN --mount=type=cache,target=/root/.cache/uv \
  uv sync --frozen --no-install-project --no-dev
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
  uv sync --frozen --no-dev
FROM base
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"
EXPOSE 8000
CMD ["uvicorn", "uv_docker_example:app", "--host", "0.0.0.0", "--port", "8000"]

Объяснение Dockerfile

Используя многоэтапную сборку, мы можем отделить сборку от развертывания и в полной мере воспользоваться преимуществами кэширования слоев Docker для ускорения сборки и получения итогового образа меньшего размера.

Этап 1: FROM python:3.12-slim-bookworm AS base

FROM python:3.12-slim-bookworm AS base

Для оптимального кэширования мы используем один и тот же базовый образ для всех этапов. Это обеспечивает совместимость между этапами сборки и развёртывания и позволяет нам использовать преимущества кэширования слоёв Docker, чтобы создавать меньше слоёв при сборке. Образ -alpine также можно использовать для создания ещё более компактного итогового образа, но в некоторых проектах может потребоваться установка дополнительных зависимостей.

Этап 2: FROM base AS builder

COPY --from=ghcr.io/astral-sh/uv:0.4.9 /uv /bin/uv
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy

В конструкторе мы копируем двоичный файл uv из официального UV-изображения с тегом конкретной версии.

UV_COMPILE_BYTECODE=1 указывает uv скомпилировать файлы Python в .pyc файлы байт-кода. Установка этого занимает немного больше времени (часть процесса сборки), но часто ускоряет время запуска приложения в контейнере.

UV_LINK_MODE=copy команда uv копирует файлы Python в контейнер из кэша, устраняя любые проблемы, связанные с символическими ссылками.

WORKDIR /app
COPY uv.lock pyproject.toml /app/
RUN --mount=type=cache,target=/root/.cache/uv \
  uv sync --frozen --no-install-project --no-dev

После настройки рабочего каталога мы копируем только файлы uv.lock и pyproject.toml в каталог /app и запускаем uv sync для установки зависимостей. Это позволяет нам использовать кэширование уровней Docker для кэширования зависимостей, которые меняются реже, перед копированием остального кода приложения.

COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
  uv sync --frozen --no-dev

После установки зависимостей и кэширования слоя мы копируем остальную часть кода приложения и снова запускаем uv sync без флага --no-install-project, чтобы установить приложение. Если исходный код приложения изменится, этот слой станет недействительным, но зависимости не нужно будет устанавливать заново.

Этап 3: FROM base (заключительный этап)

FROM base
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"

Заключительный этап начинается с создания минимального базового образа и копирования данных из этапа сборки в каталог /app . В этом случае мы задаём переменную среды PATH , включающую каталог bin виртуальной среды, чтобы можно было запускать приложение без указания полного пути к исполняемому файлу uvicorn .

EXPOSE 8000
CMD ["uvicorn", "uv_docker_example:app", "--host", "0.0.0.0", "--port", "8000"]

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *