An example project for using uv in Docker images, with a focus on best practices for developing with the project mounted in the local image.
See the uv Docker integration guide for more background.
A run.sh utility is provided for quickly building the image and starting a container. This script demonstrates best practices for developing using the container, using bind mounts for the project and virtual environment directories.
To build and run the python package in the container using docker:
docker build -q .
docker run --rm -v "%CD%:/app" -v "/app/.venv" uvThis prints out: `Hello from uv-docker-example!
or simply run the windows file: run.bat or the linux file run.sh
A Docker compose configuration is also provided to demonstrate best practices for developing using the container with Docker compose. Docker compose is more complex than using docker run, but has more robust support for various workflows.
To build and run the python package using Docker compose:
docker compose up --watch
> response
app-1 | Hello from uv-docker-example!
The Dockerfile defines the image and includes:
- Installation of uv
- Installing the project dependencies and the project separately for optimal image build caching
- Placing environment executables on the
PATH - Running the web application
The multistage.Dockerfile example extends the Dockerfile example to use multistage builds to reduce the final size of the image.
The standalone.Dockerfile example extends the multistage.Dockerfile example to use a managed Python interpreter in a multistage build instead of the system interpreter that comes with the base image.
Note that the multistage.Dockerfile and the standalone.Dockerfile are used by CI for building and testing images, but are not used for local development or devcontainers.
The .dockerignore file includes an entry for the .venv directory to ensure the .venv is not included in image builds. Note that the .dockerignore file is not applied to volume mounts during container runs.
The run.sh and run.bat script includes an example of invoking docker run for local development, mounting the source code for the project into the container so that edits are reflected immediately.
The compose.yml file includes a Docker compose definition for the web application. It includes a watch directive for Docker compose, which is a best-practice method for updating the container on local changes.
The Python application code for the project is at src/uv_docker_example/__init__.py — there's a basic function with "hello world" output.
The project at pyproject.toml includes Ruff as an example development dependency, and defines a the package as entrypoint for the application.
To check that the environment is up-to-date after image builds:
$ ./run.sh uv sync --locked
Audited 2 packages ...To enter a bash shell in the container:
$ ./run.sh /bin/bashTo build the image without running anything:
$ docker build .To build the multistage image:
$ docker build . --file multistage.Dockerfile