Containerizing a Python Project with UV
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! 😄