rattler-oci registry
Build a container image on demand from conda packages, expose it through the OCI Distribution API, and reuse package layers across pulls.
This service accepts normal OCI pull requests. The repository name encodes either a conda channel
plus package names, or a GitHub repository that contains a pixi.lock. When a client asks
for a manifest, the server solves the environment, plans package layers, writes missing blobs, and
returns an OCI image manifest.
/v2/; the docs UI below uses /_pixi/v1/dry-run.Repository Paths
Conda paths are intentionally simple. The image tag is accepted but does not change dependency solving; use :latest unless you need a stable client-side label.
Simple channel path
Resolves python and numpy from conda-forge for the server's default Linux platform.
Explicit platform and subchannel path
The pkgs separator lets the channel contain multiple path segments. A platform segment such as linux-64 can appear before pkgs.
Dry Run Layer Viewer
Dry run performs the same package query, solve, best-effort popularity lookup, and layer planning as a real manifest request, and returns packages in dependency-first topological order, but it does not build or upload missing layer blobs. Cold requests use solved-environment dependency scores immediately while ecosystem-wide popularity is warmed in the background and reused from cache.
GET /_pixi/v1/dry-run?image=<registry>/<name>:<tag>.Pulling Images
Any OCI client that can pull anonymous images can use the registry.
During the first pull, the server may need to solve dependencies and create blobs. Later pulls reuse stored manifests and layer metadata where possible.
GitHub pixi.lock
GitHub paths read pixi.lock from main, then fall back to master. The current implementation uses the default pixi environment.
Add /dev to include the repository source tarball and a pixi binary layer in the image.
Layers
Conda package layers are gzip-compressed tar layers using application/vnd.oci.image.layer.v1.tar+gzip.
The uncompressed diff ID and compressed digest are computed while the layer is written to a temporary file.
- Base image layers come from
docker.io/library/debian:stable-slim. - Conda packages are installed under
/opt/conda. - Package layer planning is based on dependency structure, package sizes, popularity scores, and a layer budget. Small environments often collapse into one conda layer when there is no large or highly reused package worth splitting out.
- Duplicate paths inside a layer are skipped with first writer wins.
HTTP API
The implemented API surface is intentionally small.
| Method | Path | Description |
|---|---|---|
GET | / | Documentation and dry-run UI. |
GET | /health | Health check. |
GET | /v2/ | OCI version check. |
GET / HEAD | /v2/<name>/manifests/<reference> | Resolve or serve an OCI image manifest. |
GET / HEAD | /v2/<name>/blobs/<digest> | Serve a config or layer blob. |
GET | /_pixi/v1/dry-run?image=... | Resolve packages and planned layers without building blobs. |
Current Limits
- This registry is pull/read-through only. It does not implement blob upload, push, or tag-list endpoints.
- Authentication is not implemented in this server.
- The dry-run endpoint reports exact package archive sizes. Actual compressed layer sizes are only known for cached layers that have already been built.
- Set
--data-dir,--package-cache-dir, and--repodata-cache-dirto writable persistent storage in production. - Large solves still consume CPU and network; production deployments should keep conservative concurrency limits.