Minimal Dev Container image for Python with uv: Debian, verified upstreams, SLSA provenance
10K+
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 preferghcr.io/bare-devcontainer/uvunless your environment requires Docker Hub, where the image isdocker.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.
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>"
}
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 | Debian variant |
|---|---|
0.12.19-trixie, 0.12.19, trixie | trixie |
0.12.19-bookworm, bookworm | bookworm |
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.
Everything from the debian base image, plus:
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.
.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.pip, pipx, or virtualenv. uv covers those workflows; uv pip provides a
pip-compatible interface against the project's environment.build-essential. Extensions that link against a system library still need its -dev
package, such as libpq-dev for psycopg2.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.
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.
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.
Content type
Image
Digest
sha256:5626d0a16…
Size
253.7 MB
Last updated
1 day ago
docker pull baredevcontainer/uv:0.12.19