Last updated: November 2nd 2026
To cache container images in a self-hosted environment, run a pull-through cache between your clients and your registries. The cache stores image layers and manifests on the first pull and serves them locally after that. Varnish Virtual Registry (formerly Varnish Orca) does this for Docker Hub, private registries and Kubernetes clusters. You deploy it on your own infrastructure and point Docker or containerd at it.
CI pipelines and Kubernetes nodes pull the same base images over and over. If a parallel build pulls a 40 MB base image 100 times, that’s around 4 GB of identical traffic to your registry from a single burst. Without a cache, that repetition causes:
| Option | What it does | Trade-off |
|---|---|---|
| Docker’s open-source registry in proxy mode | Pull-through cache for one upstream registry | One upstream per instance; no access-control checks against private registries |
| Harbor proxy cache projects | Caches images inside a Harbor installation | Requires running and maintaining Harbor |
| Artifactory or Nexus remote repositories | Proxies upstream registries inside your repository manager | Adds load to the repository manager you may be trying to protect |
| A virtual registry in front of your registries | Caches pulls from Docker Hub and private registries close to your runners | Extra component to deploy; tags are still checked upstream (see below) |
Virtual Registry sits between your clients and your registries as a pull-through cache:
:latest can change, so its manifest is checked with the upstream registry on every request by default. Digest-pinned images never change, so they’re cached long term.config.yaml file, and the default configuration already includes Docker Hub.hosts.toml.Step-by-step guides: Docker cache tutorial and using Virtual Registry as a bootstrap cache for Kubernetes.
Yes. Virtual Registry checks each user’s pull access with the registry before serving a cached image, so access control is kept without separate cached copies per user.
Not by default. Tags are checked with the registry on every request, so a changed :latest is picked up immediately. Digest-pinned images never change.
Yes, in two ways. Repeat pulls are served from cache, and you can configure a Docker Hub account so pulls no longer count against the anonymous per-IP limit.
Yes. Configure containerd on each node to use Virtual Registry as a mirror, and image pulls during scale-ups are served from the cache.
Follow the Docker cache tutorial, see how Varnish Virtual Registry fits your software delivery and CI/CD pipeline, or talk to an expert.
Running Artifactory as well? See how to reduce load on Artifactory without adding nodes.