DEV Community

Speed Up Python CI/CD 10x with uv: Migration from Pip & Poetry

📖 Original Reference: Originally published with performance benchmarks and deployment pipelines at alexmaina.dev/python-uv-github-actions.

In standard Python CI/CD pipelines, pip install or poetry install is notoriously slow, burning 2 to 5 billable minutes on every commit just resolving wheel dependencies.

uv, created in Rust by Astral (the authors of Ruff), is an extremely fast Python package and project manager designed as a drop-in replacement for Pip, Pip-tools, Virtualenv, and Poetry.

Here is how to migrate an existing project, lock dependencies with uv.lock, and reduce your GitHub Actions workflow times from minutes to seconds.

1. Quick Migration Commands

# Install uv (Linux/macOS)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install uv (Windows PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# Initialize standard PEP 621 project
uv init my-project
cd my-project

# Add dependencies with automatic lockfile update
uv add fastapi uvicorn "pydantic>=2.0"
uv add --dev pytest ruff

# Run tests instantly in isolated environment
uv run pytest

2. Optimized GitHub Actions Workflow

In .github/workflows/ci.yml, leverage the official astral-sh/setup-uv action with built-in cache keying:

name: Test & Lint Python
on:
  push:
    branches: [main]
  pull_request:
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup uv with automatic dependency caching
        uses: astral-sh/setup-uv@v5
        with:
          version: "latest"
          enable-cache: true
          cache-dependency-glob: "uv.lock"
      - name: Install required Python version
        run: uv python install 3.12
      - name: Sync dependencies from lockfile
        run: uv sync --frozen --all-extras --dev
      - name: Lint with Ruff
        run: uv run ruff check .
      - name: Run Pytest
        run: uv run pytest --maxfail=1 -q

3. Production Multi-Stage Dockerfile

Use uv during the build stage to compile wheels and copy strictly the finalized .venv into the production runtime container:

# STAGE 1: Dependency resolution & build
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
WORKDIR /app
ENV UV_COMPILE_BYTECODE=1 \
    UV_LINK_MODE=copy
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev --no-install-project
COPY . .
RUN uv sync --frozen --no-dev

# STAGE 2: Minimal runtime image
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY . /app
ENV PATH="/app/.venv/bin:$PATH"
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Author: Alessandro Mainardi - Software Developer & Computer Engineering Student @ UniBo. Explore modern tooling and software engineering guides at alexmaina.dev.

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.