Reproducible Builds with uv.lock

Crossbar.io uses uv for dependency management and reproducible builds. The uv.lock file captures the exact versions of all dependencies, ensuring consistent installations across different machines and over time.

Why uv.lock?

As an application (not a library), Crossbar.io benefits from locked dependencies:

  • Reproducibility: Every installation gets the exact same package versions

  • Security: Known-good versions are captured and verified

  • Docker builds: Production containers use the same dependencies tested in CI

  • Debugging: Issues can be reproduced reliably across environments

Note

The WAMP libraries (txaio, autobahn-python, zlmdb, cfxdb, wamp-xbr) do NOT commit uv.lock files. Libraries should “float” on the ecosystem to ensure compatibility with a wide range of downstream users.

Installation using uv sync

The uv sync command installs dependencies from uv.lock. Different installation modes are available depending on your needs:

Runtime Dependencies Only

For production use or when you just need to run Crossbar.io:

uv sync

This installs only the packages required to run Crossbar.io (~160 packages).

With Development Tools

For development with testing and linting tools:

uv sync --extra dev

This adds pytest, ruff, bandit, and other development tools.

With Documentation Tools

For building the documentation:

uv sync --extra docs

This adds Sphinx, Furo theme, sphinx-autoapi, and other documentation tools.

All Dependencies

To install everything (all extras):

uv sync --all-extras

Understanding Markers

The uv.lock file uses markers to track which packages belong to which extras. For example:

{ name = "pytest", marker = "extra == 'dev'" }
{ name = "sphinx", marker = "extra == 'docs'" }

Packages with markers are only installed when that extra is explicitly requested. This keeps runtime installations minimal while allowing a single lock file to capture all dependency configurations.

Frozen Installation

For maximum reproducibility (e.g., in Docker), use:

uv sync --frozen

This fails if uv.lock is missing or outdated, ensuring you always install from a known-good lock file.

Updating uv.lock with just

To update the lock file with the latest compatible versions:

just update-uvlock

This runs uv lock --python 3.11 to ensure compatibility with the lowest supported Python version, then displays an analysis of the updated lock file.

When to Update

Update uv.lock when:

  • Adding or removing dependencies in pyproject.toml

  • Before a release to capture latest security patches

  • When CI reports outdated dependencies

  • After modifying version constraints

The update process:

  1. Resolves all dependencies for Python 3.11+

  2. Captures exact versions in uv.lock

  3. Displays analysis summary

  4. Commit the updated uv.lock to Git

Analyzing uv.lock with just

To analyze the current lock file:

just analyze-uvlock

Example output:

===============================================================================
                         uv.lock Dependency Analysis
===============================================================================

Total packages in uv.lock: 263

Installation modes (using uv sync):
─────────────────────────────────────────────────────────────────────────────

  uv sync                      Runtime deps only (153 packages)
  uv sync --extra dev          Runtime + dev tools (247 packages)
  uv sync --extra docs         Runtime + docs tools (186 packages)
  uv sync --all-extras         All packages (257 packages)

Extra markers in uv.lock (dependency graph entries):
─────────────────────────────────────────────────────────────────────────────

  extra == 'dev':        29 entries
  extra == 'docs':       12 entries

Note: Packages with extra markers are only installed when that extra is
      requested. The markers ensure selective installation.

===============================================================================

Docker Production Builds

For production Docker images, use the frozen lock file:

FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv

# Clone specific tag to get the uv.lock
RUN git clone --branch v25.12.2 https://github.com/crossbario/crossbar /app
WORKDIR /app

# Install EXACTLY what was tested - frozen deps, no dev tools
RUN uv sync --frozen --no-dev --no-editable

ENV PATH="/app/.venv/bin:$PATH"
ENTRYPOINT ["crossbar"]

This ensures the production container has exactly the same dependencies that were tested in CI and verified during development.

References