2 minute read

Introduction

Hello! 👋

I wanted to write this short article about containerizing a Python project that uses uv as a project manager. I will present what UV is and how to write a Dockerfile for such a project, that I will also use it as a reference for the future.

What is UV?

UV is a project manager and package manager for Python projects, and it’s very fast 🚀!

Its speed comes from the fact that it’s written in Rust 🦀 from scratch.

How does it differ from pip

It differs from pip in that it’s way faster and much more efficient, secondly pip is only a package manager while uv does much more and is more modern.

UV was created to replace tools like:

  • pip
  • pip-tools
  • pipx
  • poetry
  • pyenv
  • twine
  • virtualenv

This means that uv can be used to install different Python versions like 3.13, 3.12, 3.11 and to create virtual environments (venv’s). Also when using the uv tool command (which replaces pipx) it can be used to install tools written in Python in a separate environment from the application environment.

To execute a tool, you can use the uv run tool name command and the tool name. I usually only use the following tools: black, isort and ruff.

Dockerfile

This is my dockerfile that I use for projects:

FROM python:3.12-slim-bookworm

# The installer requires curl (and certificates) to download the release archive
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates

# Download the latest installer
ADD https://astral.sh/uv/install.sh /uv-installer.sh

# Run the installer then remove it
RUN sh /uv-installer.sh && rm /uv-installer.sh

# Ensure the installed binary is on the `PATH`
ENV PATH="/root/.local/bin/:$PATH"

# copy code
WORKDIR /app

COPY pyproject.toml /app
RUN uv sync

COPY . .

CMD ["uv", "run", "python", "-m", "app.main"]

The reason I run uv sync before COPY . . is to benefit from the caching that the container builder does for each layer. So that if I have a small change to the code and don’t modify the dependencies in pyproject.toml the container build will be fast, because all the previous layers will be taken from cache and only the last two layers will be used for the build:

COPY . .
CMD ["uv", "run", "python", "-m", "app.main"]

Conclusion

In this article we explored how to containerize a Python project that uses UV.

UV proves to be a modern and fast alternative to traditional tools like pip and poetry, offering extended functionality for managing virtual environments and dependencies.

See you next time! 😄