Learning Platform
Глоссарий Troubleshooting
Урок 17.03 · 22 мин
Средний
dockerpythonuvpoetry

uv, poetry, pip-tools

pip — стандарт для установки пакетов с 2008 года. Он работает, его все знают. Но он медленный, и его dependency resolver всё ещё временами выдаёт сюрпризы. С 2020-х появилась волна альтернатив: poetry, pdm, pip-tools, и финальный игрок — uv от Astral (создатели ruff).

В мае 2026 uv стал стандартом для нового Python-DE проекта. Этот урок: чем он отличается от pip, как использовать в Dockerfile, когда стоит остаться на poetry, что такое lock-файлы.


Почему pip медленный

Pip написан на чистом Python. Что делает при pip install pandas:

  1. Резолвит зависимости: дергает API PyPI для каждого пакета, читает manifest, разбирается с version constraints.
  2. Скачивает wheels.
  3. Распаковывает в site-packages.
  4. Запускает install hooks (если есть).

Самый медленный шаг — резолюция. На проекте с 30 транзитивными зависимостями pip может тратить 10-20 секунд только на «думанье».


Что такое Linux: ядро, GNU и system calls

uv: Rust-implementation

uv — реализация pip и pip-tools на Rust, от Astral. Совместима с pip CLI, но в 10-100 раз быстрее на типичных операциях.

Установка:

# macOS
brew install uv

# Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Через pip (если уже есть Python)
pip install uv

Использование как drop-in replacement для pip:

uv pip install pandas
# то же что pip install pandas, но за 0.5 сек вместо 4 сек

uv pip install -r requirements.txt
# то же что pip install -r requirements.txt

Бенчмарки от Astral (на проекте django + 40 зависимостей):

  • pip install — 30 секунд.
  • uv pip install — 3 секунды.

Это 10x. Для проекта с pandas + scipy + sklearn — ещё больше (50-100x на cold-cache).


uv в Dockerfile

Простой вариант:

FROM python:3.13-slim

RUN pip install --no-cache-dir uv

WORKDIR /app

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

COPY . .
CMD ["python", "main.py"]

--system важен: uv по умолчанию ставит в virtualenv. --system означает «ставь в глобальный Python» — это то, что мы хотим в Docker (контейнер сам себе изолирует, virtualenv лишний).

С BuildKit cache (рекомендуется):

# syntax=docker/dockerfile:1.7
FROM python:3.13-slim

# uv напрямую как бинарь (без pip install — быстрее)
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

WORKDIR /app

COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/uv \
    uv pip install --system -r requirements.txt

COPY . .
CMD ["python", "main.py"]

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv — берём готовый бинарь uv из официального registry. Это быстрее pip install uv (нет pip-резолюции, просто copy файла).

Bench: проект с airflow + pandas + 25 зависимостей.

ПодходCold buildHot rebuild (правка кода)
pip install120 сек5 сек (layer cache)
uv pip install15 сек5 сек
uv + BuildKit cache15 сек5 сек
uv + BuildKit cache (после смены реквайрментов)5 секn/a

uv даёт ускорение даже без BuildKit cache.

pip vs uv: где разница
pip installPython implementation. Серийная резолюция, серийный download через urllib
vs
uv pip installRust implementation. PubGrub resolver, параллельный download, эффективный кэш на content-addressable storage
Резолюция 30 depspip тратит секунды на dependency resolution, дёргая API PyPI
Резолюция 30 depsuv использует PubGrub, параллельный сетевой ввод-вывод
Скачивание wheelspip качает один-за-другим (есть pip download --no-build-isolation)
Скачивание wheelsuv качает параллельно через async I/O, переиспользует connections

uv: новый формат проекта (pyproject.toml)

uv поддерживает PEP 621 — стандартный формат pyproject.toml:

[project]
name = "my-etl"
version = "0.1.0"
dependencies = [
    "pandas>=2.2",
    "sqlalchemy>=2.0",
    "psycopg[binary]>=3.2",
]

Команды:

uv venv                    # создать .venv
uv pip install -e .        # установить проект как editable
uv lock                    # сгенерить uv.lock
uv sync                    # установить точно из lock

uv.lock — это lock-файл с точными версиями всего дерева зависимостей. Аналог poetry.lock или Cargo.lock. Коммитится в git, гарантирует воспроизводимость.

В Dockerfile:

# syntax=docker/dockerfile:1.7
FROM python:3.13-slim

COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

WORKDIR /app

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

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

CMD [".venv/bin/python", "main.py"]

--frozen запрещает обновление lock-файла (если рассинхрон — fail). --no-install-project ставит только зависимости, не сам проект (это для layer cache: deps отдельно от кода).


Poetry

poetry — другой популярный менеджер, появился в 2018, написан на Python. Сильные стороны: красивый CLI, хорошие defaults, build-system’ы интегрированные. Слабые: медленнее uv, иногда странные edge cases в резолверке.

В Dockerfile с poetry:

FROM python:3.13-slim AS builder

RUN pip install poetry==1.8.0

WORKDIR /app

COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false \
    && poetry install --no-root --only main

COPY . .

CMD ["python", "main.py"]

virtualenvs.create false — поставить в системный Python (как uv --system).

В 2026 года тренд — poetry export -f requirements.txt для извлечения requirements.txt, а дальше уже pip / uv. Это позволяет использовать poetry для управления и lock’ом, а в Docker — быстрый uv:

# На dev-машине
poetry add pandas
poetry export -f requirements.txt --output requirements.txt
git commit -am "Add pandas"
# В Dockerfile
FROM python:3.13-slim
COPY requirements.txt .
RUN uv pip install --system -r requirements.txt

pip-tools (pip-compile)

pip-tools — старшая школа: deterministic lock-файл из requirements.in. requirements.in пишешь руками, pip-compile генерит requirements.txt с pinned версиями.

requirements.in:

pandas>=2.2
sqlalchemy>=2.0
psycopg[binary]
pip install pip-tools
pip-compile requirements.in
# Генерит requirements.txt с точными версиями + хешами

# Обновить:
pip-compile --upgrade requirements.in

requirements.txt после:

pandas==2.2.3
    # via -r requirements.in
sqlalchemy==2.0.36
    # via -r requirements.in
psycopg==3.2.3
    # via -r requirements.in
...

В Dockerfile — обычный pip install -r requirements.txt. Простой и понятный паттерн, ничего магического.

В 2026 — это устаревающий подход. uv покрывает всё, что делал pip-tools, плюс быстрее.


Что выбрать в 2026

ИнструментКому подходитСкоростьКогда брать
pipвсем (default)медленноLegacy, простые проекты
pip-toolsкомандам с requirements.inсреднеЕсли уже используется
poetryкомандам с pyproject.toml + lockмедленноЕсли уже используется
uvновые проектыочень быстроDEFAULT для нового DE-проекта

Для нового Junior-DE проекта в 2026 — uv. Он:

  • В 10-100x быстрее pip — экономит часы CI-времени в год.
  • pip-совместимый CLI — знание pip не пропадает.
  • Поддерживает pyproject.toml + lock.
  • Активно развивается, backed by Astral (ruff team).

Реальный bench

Проект: airflow + pandas + sqlalchemy + dbt-postgres + 30 транзитивных deps.

# Чистая сборка, BuildKit cache очищен

# Вариант A: pip
docker build -f Dockerfile.pip --no-cache -t bench-pip .
# 145 сек

# Вариант B: uv (без BuildKit cache)
docker build -f Dockerfile.uv --no-cache -t bench-uv .
# 22 сек

# Вариант C: uv + BuildKit cache
docker build -f Dockerfile.uv-cache --no-cache -t bench-uv-cache .
# 18 сек

# Ребилд после добавления одной зависимости:
# pip — 80 сек (тянет всё заново)
# uv — 5 сек (incremental)

uv даёт ~8x ускорение на cold build. В CI это разница между «PR ждёт 3 минуты сборки» и «PR ждёт 25 секунд».


Pitfall: native deps

uv ускоряет резолюцию и скачивание, но не сборку из исходников. Если для какого-то пакета нет wheel под твою платформу — uv будет вызывать pip-build, и компиляция займёт те же минуты, что и с pip.

# Если pandas нет wheel — фигня будет с любым менеджером
FROM python:3.13-alpine
RUN uv pip install --system pandas
# Будет компилировать минут 5

Решение: использовать slim-base (где manylinux wheels работают) и не лезть в edge cases.

uv в production-Dockerfile
COPY --from=astral-sh/uvБерём готовый бинарь uv одной layer-инструкцией, без pip install
COPY requirements.txtОтдельный слой для зависимостей — layer cache если файл не менялся
--mount=type=cache uv pip installBuildKit cache + uv: 100x на cold, 10x на warm — комбо для скорости
COPY . .Код копируется в последнюю очередь — изменения в коде не влияют на установленные зависимости

Попробуй сам

  1. Установи uv: brew install uv или pip install uv. Проверь: uv --version.
  2. Создай простой проект, requirements.txt:
    pandas
    sqlalchemy
    psycopg[binary]
  3. Сравни время pip install -r requirements.txt и uv pip install -r requirements.txt локально.
  4. Собери два Dockerfile (один pip, один uv), замерь время:
    time docker build --no-cache -f Dockerfile.pip -t pip-test .
    time docker build --no-cache -f Dockerfile.uv -t uv-test .
    Запиши разницу.
  5. Добавь BuildKit cache к uv-варианту. Снова замерь cold build. Должно стать ещё чуть быстрее (за счёт ещё-более-эффективного uv cache).
  6. Бонус: используй pyproject.toml + uv.lock вариант. uv lock создаст lock-файл. uv sync --frozen в Dockerfile.

Проверка знанийKnowledge check
Чем uv от Astral отличается от pip и почему для новых DE-проектов в 2026 году uv — рекомендуемый выбор?
ОтветAnswer
uv — это реализация pip и pip-tools на Rust, написанная командой Astral (создатели ruff). Главное отличие — скорость: 1) Резолюция зависимостей. pip написан на Python, серийный, дёргает PyPI API по одному пакету. На 30 транзитивных зависимостях — 3-5 секунд. uv использует Rust + PubGrub algorithm + параллельный async I/O — 0.2 секунды на тот же набор. 10-25x ускорение. 2) Скачивание wheels. pip качает последовательно. uv качает параллельно через async networking, переиспользует HTTP-соединения. 5-10x ускорение. 3) Кеш — content-addressable storage с хешами. Эффективнее pip-кеша. В сумме на проекте airflow + pandas + 25 deps: pip install 60 секунд, uv pip install 6 секунд. На больших проектах разница ещё больше — 100x встречается. Почему default для нового DE-проекта в 2026: - pip-совместимый CLI (uv pip install -r requirements.txt). Не надо учить новое. - Поддерживает pyproject.toml + uv.lock (PEP 621 standard) — современный формат проекта с deterministic lock. - В Docker через COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv — готовый бинарь, ставится за миллисекунды. - Активная разработка Astral, гарантированная поддержка. - В CI разница 60 секунд vs 6 секунд = годовая экономия часов compute и времени разработчиков. Когда оставаться на pip: legacy-проект с устоявшейся CI и нет ресурсов на миграцию. Когда poetry: команда уже на poetry, всё работает, не ломаем. Иначе — uv.

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 4. uv от Astral в 2026 — какие технические причины делают его в 10-100x быстрее pip?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5