Distribution

The OCI-compliant, self-hosted container registry toolkit powering Docker Hub, GHCR, and GitLab Registry.

Tool
Go
vv2.8.3+incompatible
10,604stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
91/100Excellent
Development Activity88
Maintenance80
Community96
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture88
Code Quality85
Innovation82
Learning Curve70

Distribution (formerly docker/distribution, now maintained under the distribution/distribution org) is the reference implementation of the OCI Distribution Specification — the toolkit that stores and serves container images and other OCI artifacts over HTTP. It ships as both a production-ready registry server binary (cmd/registry) and a set of Go libraries for blob/manifest storage, and it underpins Docker Hub, GitHub Container Registry, GitLab Container Registry, DigitalOcean Container Registry, and the CNCF Harbor project.

Pluggable storage drivers (filesystem, in-memory, S3, Azure Blob, GCS) and middleware (token/htpasswd auth, pull-through proxy caching, webhook notifications) let operators run anything from a single private registry to a globally distributed public one, while the same manifest, blob, and digest-handling code is reused across the container ecosystem’s registry implementations.

What You Get

  • A standalone registry server binary (cmd/registry) driven by a Cobra CLI and configured entirely via YAML
  • Pluggable storage backends — filesystem, in-memory, S3, Azure Blob, GCS — swapped purely through configuration, no code changes
  • Pull-through proxy caching so a private registry can mirror and cache an upstream registry like Docker Hub
  • A garbage-collect subcommand plus catalog pagination and blob/manifest handling built for large-scale operation
  • A webhook notification system that emits HTTP events on blob and manifest pushes for custom automation

Common Use Cases

  • Running a private, self-hosted container registry behind your own auth and network perimeter
  • Mirroring/proxying Docker Hub or another upstream registry to cut egress costs and dodge anonymous-pull rate limits
  • Powering a hosted registry product — Docker Hub, GHCR, GitLab Registry, and Harbor all build on it
  • Embedding its Go storage/manifest packages into custom registry or image-scanning tooling

Under The Hood

Architecture The project is organized as a layered service: registry/handlers implements the HTTP API surface (blob, manifest, tag, catalog endpoints) on top of registry/storage, which defines blob/manifest stores backed by a pluggable storage/driver interface (filesystem, S3, Azure, GCS, in-memory each implement the same StorageDriver contract via a factory registry). Cross-cutting concerns — auth (registry/auth, with htpasswd/silly/token strategies), proxy caching (registry/proxy), and notifications (notifications/) — are wired in as middleware/listeners around the core Namespace/Repository/BlobStore interfaces defined at the module root (registry.go, blobs.go). The cmd/registry binary is a thin Cobra CLI (registry.RootCmd) that composes these layers via blank-import side-effect registration, so what breaks if a core abstraction changes is contained to a single storage driver or middleware, not the whole request path.

Tech Stack Go module github.com/distribution/distribution/v3, targeting Go 1.25. HTTP routing via gorilla/mux and gorilla/handlers; CLI via spf13/cobra; OCI types via opencontainers/image-spec and opencontainers/go-digest; cloud storage clients for AWS S3 (aws-sdk-go), Azure Blob (azure-sdk-for-go), and GCS (cloud.google.com/go/storage); Redis caching via redis/go-redis; observability via OpenTelemetry (go.opentelemetry.io/otel) and docker/go-metrics/Prometheus. Build/release tooling uses Make, Docker Bake (HCL), and GitHub Actions.

Code Quality Extensive test coverage — dozens of _test.go files sit alongside nearly every implementation file (handlers, storage drivers, manifest stores, proxy layers), using the standard library testing package plus stretchr/testify for assertions and alicebob/miniredis for Redis-dependent tests. Errors are modeled as typed values (ErrBlobUnknown, ErrBlobInvalidDigest, etc.) rather than raw strings, golangci-lint is configured project-wide (.golangci.yml), and CI runs build/conformance/security-scorecard workflows on every push.

What Makes It Unique Distribution isn’t a wrapper around someone else’s registry API — it’s the origin implementation that the OCI Distribution Specification itself grew out of, and multiple unrelated products (Docker Hub, Harbor, GitLab Registry, DigitalOcean’s registry) run it or a fork of it directly rather than reimplementing the spec. Its storage-driver abstraction and pull-through proxy design let the same codebase serve as a from-scratch private registry, a caching mirror, or the backend for a commercial hosted product with no architectural rework.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search