Expand description
ferro-oci-server
OCI Distribution Spec v1.1 (opencontainers/distribution-spec) and
Docker Registry HTTP API v2 (docker/distribution) for FerroRepo.
Phase 1 scope (wired in this crate):
GET /v2/version check and auth challenge (spec §3.2);GET /v2/_catalogrepository catalog withn/lastpagination (spec §3.5);GET /v2/{name}/tags/listtag listing with pagination (spec §3.6);GET|HEAD|DELETE /v2/{name}/blobs/{digest}(spec §3.2 / §4.9);POST|PATCH|PUT /v2/{name}/blobs/uploads/{uuid?}— monolithic and chunked uploads (spec §4.3–§4.8);GET|HEAD|PUT|DELETE /v2/{name}/manifests/{reference}(spec §3.2 / §4.4 / §4.9);GET /v2/{name}/referrers/{digest}referrers API (spec §3.3).
The Phase 1 exit gate is 100 % pass on the
opencontainers/distribution-spec conformance suite and interop
with docker, podman, crane, skopeo, and nerdctl.
§Quick start
Build an AppState from a blob store and a metadata plane, hand
it to router(), optionally merge in the Kubernetes health probes
from probe_routes, and serve it with axum:
use std::sync::Arc;
use ferro_blob_store::InMemoryBlobStore;
use ferro_oci_server::{AppState, InMemoryRegistryMeta, probe_routes, router};
let state = AppState::new(
Arc::new(InMemoryBlobStore::new()),
Arc::new(InMemoryRegistryMeta::new()),
);
let app = router(state).merge(probe_routes());
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
axum::serve(listener, app).await?;After that, docker push localhost:8080/myimage:latest (or
podman / crane / skopeo) works against the running server.
§Integration story
- Storage — blob bytes live behind
ferro_blob_store::BlobStore(use the bundledferro_blob_store::FsBlobStorefor a filesystem registry orferro_blob_store::InMemoryBlobStorefor tests). Metadata (manifests, tags, upload sessions, referrers) lives behind theRegistryMetatrait;InMemoryRegistryMetaships as the single-node reference impl, and you can supply a SQLite/Postgres-backed impl of your own. - Auth — handlers are open by design. Layer authentication and
authorization as
towermiddleware above therouter(). - Deployment — a runnable
ferro-oci-serverbinary ships with this crate (seesrc/bin/ferro-oci-server.rs); it readsFERRO_OCI_LISTENandFERRO_OCI_STORAGE_DIRfrom the environment, exposes the/live,/healthz, and/readyprobes, and shuts down gracefully onSIGTERM/SIGINT.
Re-exports§
pub use error::OciError;pub use error::OciErrorBody;pub use error::OciErrorCode;pub use error::OciErrorInfo;pub use error::OciResult;pub use manifest::Descriptor;pub use manifest::ImageIndex;pub use manifest::ImageManifest;pub use manifest::empty_image_index;pub use media_types::ManifestKind;pub use media_types::classify_manifest_media_type;pub use metrics::Metrics;pub use metrics::MetricsState;pub use metrics::instrument;pub use metrics::metrics_routes;pub use reference::MAX_NAME_LENGTH;pub use reference::MAX_TAG_LENGTH;pub use reference::Reference;pub use reference::validate_name;pub use registry::DEFAULT_MAX_UPLOAD_SESSIONS;pub use registry::DEFAULT_UPLOAD_SESSION_TTL;pub use registry::InMemoryRegistryMeta;pub use registry::METADATA_FILE_NAME;pub use registry::ReferrerDescriptor;pub use registry::RegistryMeta;pub use registry::SessionLimits;pub use registry::UploadAdmission;pub use router::AppState;pub use router::probe_routes;pub use router::router;pub use serve::Config;pub use serve::build_app;pub use serve::build_app_persisted;pub use serve::init_tracing;pub use serve::serve;pub use router::MAX_BODY_BYTES;pub use upload::ContentRange;pub use upload::MAX_UPLOAD_SESSION_BYTES;pub use upload::UploadState;
Modules§
- error
- OCI error response shape and mapping to HTTP status codes.
- handlers
- HTTP handlers for the
/v2/**OCI Distribution endpoints. - manifest
- OCI image manifest and image index types.
- media_
types - OCI / Docker media type constants.
- metrics
- Prometheus instrumentation for
ferro-oci-server. - reference
- Repository-name and reference parsing.
- registry
- Registry metadata plane.
- router
- Axum router factory that wires the
/v2/**OCI endpoints. - serve
- Runnable-server assembly: environment configuration, app wiring, and the bind+serve loop with graceful shutdown.
- upload
- Blob-upload session state machine.
Constants§
- CRATE_
NAME - Crate name, exposed for diagnostics and
/metricslabelling.