Sign inSign up

baredevcontainer/uv

By baredevcontainer

•Updated 1 day ago

Minimal Dev Container image for Python with uv: Debian, verified upstreams, SLSA provenance

Image
Security
Languages & frameworks
Developer tools
0

10K+

baredevcontainer/uv repository overview

⁠uv (python)

Mirror. This Docker Hub repository mirrors ghcr.io/bare-devcontainer/uv, under the same tags and with the same digests. GitHub Container Registry receives every build first and applies no pull rate limit, so prefer ghcr.io/bare-devcontainer/uv unless your environment requires Docker Hub, where the image is docker.io/baredevcontainer/uv.

This page is rendered from the image's README in bare-devcontainer/images⁠. That is the repository "this repository" refers to below.

Dev container image for Python development, with uv⁠ installed, built on the debian⁠ base image.

Like every image in this repository, it is minimal, built only from upstreams verified at build time, and published with SLSA provenance, a GitHub artifact attestation, and an SBOM; it runs as the non-root user dev. Why these images⁠ explains the reasoning, and Verifying the image⁠ below shows how to check a build.

⁠Image

ghcr.io/bare-devcontainer/uv:<tag>

Reference it from .devcontainer/devcontainer.json, pinning the digest as well as the tag:

{
  "image": "ghcr.io/bare-devcontainer/uv:trixie@sha256:<digest>"
}

⁠Dev Container Template

A ready-to-use Dev Container template for this image is available at bare-devcontainer/templates⁠. It provides the recommended configuration for this image, including security hardening and volume mounts that persist cache directories for faster rebuilds.

⁠Tags

TagsDebian variant
0.12.19-trixie, 0.12.19, trixietrixie
0.12.19-bookworm, bookwormbookworm

Tags are also published with a date suffix on each build (e.g., 0.12.19-trixie-<YYYYMMDD>).

The version in these tags is the version of uv itself, not of any Python interpreter.

⁠Installed software

Everything from the debian⁠ base image, plus:

  • uv⁠ (uv, uvx), with bash completions installed

~/.local/bin is on PATH under a Dev Container client, so tools installed with uv tool install resolve without further setup. Running the image without one (docker run, a CI job's container:) leaves the directory off PATH.

⁠Not installed

  • No project Python interpreter. uv downloads and manages the CPython version the project declares in .python-version or in pyproject.toml's requires-python, so the version in use is the one the project asks for. The base image's system python3 exists for scripting and is not the interpreter uv builds environments from.
  • No pip, pipx, or virtualenv. uv covers those workflows; uv pip provides a pip-compatible interface against the project's environment.
  • No development headers beyond libc. uv installs prebuilt wheels where they exist; packages with no wheel for the platform are compiled with the base image's build-essential. Extensions that link against a system library still need its -dev package, such as libpq-dev for psycopg2.

⁠Working with interpreters

uv sync creates the project's environment and installs the interpreter it needs; uv run does the same on first use. To do it when the container is created rather than on first use, run uv sync from a postCreateCommand.

Two directories are worth persisting across container rebuilds as volumes:

  • ~/.local/share/uv — the managed Python installations. Interpreters are re-downloaded on every rebuild unless this directory survives.
  • ~/.cache/uv — the wheel and download cache.

UV_LINK_MODE=copy is set in the image. uv installs packages into a project's .venv by hardlinking them out of its cache, which requires both to be on one filesystem; in a dev container the cache is in the container filesystem or a volume while the project is a bind mount, so uv would warn and copy on every uv sync anyway. Override the variable if your setup does keep the two together.

⁠Supply chain

uv is downloaded from GitHub Releases⁠ and verified against a checksum committed to this repository (uv/uv-amd64.sha256, uv/uv-arm64.sha256).

uv publishes a checksum next to each release tarball, but it comes from the same release as the tarball, so that checksum is not what is committed — the committed one is derived here, and only from a tarball whose origin has been established. .github/workflows/update-material.yml runs uv/checksum.sh whenever the pinned version changes, and the script records a digest only after gh attestation verify has confirmed that the tarball's build provenance⁠ was signed by uv's release workflow at the commit the version's tag points to. The resulting checksum is committed and reviewed like any other change, so what the image build trusts is a digest this repository accepted, rather than one the release host served alongside the tarball.

Note that this covers the uv binary only. Interpreters and packages that uv installs at runtime are fetched from their own upstreams under uv's own verification, outside this image's build pipeline.

⁠Verifying the image

Every build is published with SLSA provenance, a GitHub artifact attestation, and an SBOM. The attestation confirms that an image was built by the release workflow of this repository and has not been altered since:

gh attestation verify oci://ghcr.io/bare-devcontainer/uv:<tag>@sha256:<digest> \
  --owner bare-devcontainer

The Docker Hub mirror carries the same digests, so the same command verifies an image pulled from docker.io/baredevcontainer/uv. Verifying Published Images⁠ covers inspecting the provenance and the SBOM as well.

Tag summary

Content type

Image

Digest

sha256:5626d0a16…

Size

253.7 MB

Last updated

1 day ago

docker pull baredevcontainer/uv:0.12.19