Library / SDK
DaoCloud/public-image-mirror avatar
DaoCloud/public-image-mirror

DaoCloud public-image-mirror: a practical prefix-based accelerator for gcr, ghcr, quay and other registries

gcr . Ollama Ollama Docker Deepseek-R1 ollama DeepSeek Ollama [ ] Made with contrib.rocks.

15,068 stars1,566 forksShellApache-2.0

At a glance

What is it?
DaoCloud public-image-mirror provides a set of public registry mirrors accessed by adding a prefix or replacing a hostname. It uses a lazy-loading cache with a 30-day retention window, which shapes both its usefulness and its limitations.
Who is it for?
Adopt it if you are in mainland China and need faster pulls from gcr, ghcr, quay, registry.k8s.io, or mcr, and you can tolerate a public, rate-limited service with a 30-day cache. Do not adopt it if you require guaranteed availability, need images older than 30 days without re-sync, or cannot accept the risk of 404s from expired blobs.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What this mirror actually accelerates and who needs it

The project solves a narrow but painful problem: pulling container images from registries hosted outside mainland China, such as gcr.io, ghcr.io, quay.io, registry.k8s.io, and mcr.microsoft.com, is slow or unreliable. DaoCloud operates a set of public mirror endpoints that sit in front of those registries and cache image content. The intended users are developers and operators in China who need Kubernetes components, CI/CD images, or model-serving containers like Ollama without waiting for a multi-minute pull. The README is explicit that this is only a mirror of the upstream registries, not a separate distribution. It does not change image content; all sha256 hashes match the source. That constraint is the core promise and also the boundary of what the project can offer.

The two access modes: prefix addition versus host replacement

The recommended way to use the mirror is to add a prefix to the image reference. For example, docker.io/library/busybox becomes m.daocloud.io/docker.io/library/busybox. This form works for any registry that the service supports, because the full original reference is preserved after the mirror host. The alternative is host replacement, where you swap the registry hostname with a dedicated mirror subdomain, such as docker.m.daocloud.io for docker.io or gcr.m.daocloud.io for gcr.io. The README warns that host replacement rules are manually configured and not recommended, except for docker.io where it can be used as a Docker registry-mirror. The distinction matters: prefix addition is generic and requires no per-registry configuration, while host replacement is a fixed mapping that only exists for the registries listed in the table. If you need a registry not in that table, prefix addition is the only path.

Lazy loading and the 30-day cache: the mechanism behind the mirror

The mirror does not pre-fetch every image. Instead it uses a lazy-loading mechanism. When you request an image, the mirror fetches the manifest and blobs from the upstream registry on demand, caches them, and serves them to you. The README states that all sha256 hashes remain identical to the source, which is the expected behavior for a transparent pull-through cache. However, the cache is not permanent. Cached content is retained for 30 days. After that, a re-request triggers a fresh sync from upstream. The manifest cache has a 1-hour memory lifetime, so a tag update upstream will not be reflected in the mirror until one hour later. Blob cache memory lasts 1 minute. The README explicitly warns that if a blob reaches the 30-day limit and gets deleted during that 1-minute window, a pull can return a 404. This is a real failure mode: you can hit a 404 on an image that existed moments before. The project's own guidance is to prefer @sha256 digests over mutable tags, because a digest reference is immutable and will trigger a re-sync when needed. This lazy design keeps the service cheap to run but makes it unsuitable for workloads that require instant availability of rarely-pulled images.

Getting it running: from a one-line docker run to daemon.json

The quickest start is a direct image pull with the prefix. The README gives: docker run -d -P m.daocloud.io/docker.io/library/nginx. That is the entire onboarding for a single image. For Docker daemon-wide acceleration, you add a registry-mirror entry in /etc/docker/daemon.json: {"registry-mirrors": ["https://docker.m.daocloud.io"]}. This only works for docker.io, not for gcr or quay, because Docker's registry-mirrors mechanism only applies to Docker Hub. Podman is more flexible. The README shows a registries.conf snippet where you can define a mirror for each foreign registry, for example location = "gcr.io" with mirror location = "gcr.m.daocloud.io". This is a concrete advantage of Podman over Docker for multi-registry acceleration. For Kubernetes, the README covers kubeadm by setting imageRepository to k8s.m.daocloud.io, and kind by using m.daocloud.io/docker.io/kindest/node:v1.22.1. The containerd path references the official hosts.md documentation and a kubespray variable. There is also a webhook-based tool called repimage that rewrites image fields in new Pods without touching your YAML, installed via a kubectl create command. These are real commands you can copy, but note that the exact behavior of repimage is not described beyond the README's summary.

Ollama and DeepSeek acceleration: the experimental edge

A notable section of the README covers accelerating Ollama and DeepSeek models. For Ollama, you can run the container with docker.m.daocloud.io/ollama/ollama, both CPU and GPU variants. The GPU version requires the Nvidia Container Toolkit. For DeepSeek-R1, the mirror offers an experimental endpoint: ollama.m.daocloud.io. The command is docker exec -it ollama ollama run ollama.m.daocloud.io/library/deepseek-r1:1.5b. The README is candid that this is experimental and that the official Ollama source is already fast for many users. This is a useful admission: the mirror is not always the best path. If the official source is fast enough, you do not need the mirror. The existence of this section suggests the project is expanding beyond pure container registries into model artifacts, but it is clearly marked as a work in progress. The same 30-day cache and lazy-loading rules apply, so model blobs may also expire and require re-sync.

Operational constraints: rate limits, congestion, and the 01:00 to 07:00 window

The README contains two operational warnings that any adopter must read. First, there is a whitelist and rate-limiting policy, details of which are in issue #2328. The README does not specify the limits, but it tells you to consult that issue. Second, the service is very crowded outside certain hours. The README explicitly recommends pulling during off-peak hours, specifically 01:00 to 07:00 Beijing time, and states that other time periods are 'very crowded'. This is a strong signal that the public service is not a guaranteed-SLA infrastructure. If your CI pipeline runs at 10:00 Beijing time, you may face slow pulls or throttling. The project also provides a sync queue status page and a service status page, which are useful for verifying current health. The 1-hour manifest cache means that if you just pushed a new tag upstream, the mirror will not see it for up to 60 minutes. This is a real limitation for workflows that rely on latest tags or rapid iteration. The README's advice to use @sha256 digests is the only mitigation offered.

Maintenance, upgrades, and the alternative of running your own cache

The project is a public service, not software you install. The maintenance cost is on DaoCloud's side, not yours. However, the README points to a local cache deployment document under docs/local-cache, which suggests you can run your own mirror inside your network. That is a different cost model: you operate the cache, you control the retention, and you avoid the public congestion. The backend code is open source at OpenCIDN/ocimirror, so you could inspect or even deploy it. The license is Apache-2.0, which permits commercial use and modification, but the README does not describe the backend's operational requirements. If you choose the public service, your upgrade path is trivial: you do nothing. If you choose a local cache, you inherit the maintenance burden. The alternative to this mirror is to use the official registries directly, or to run your own pull-through cache like Harbor or a plain Docker registry with a mirror configuration. The difference is that this project offers a hosted, zero-setup option with a fixed set of upstream registries, while a self-hosted cache gives you control over retention and rate limits but requires infrastructure to run.

When the mirror is the wrong tool

The 30-day cache expiration is the biggest reason to avoid this service for production-critical pulls. If your team pulls a specific image only once a month, the mirror may have expired it, and the next pull will trigger a re-sync that could be slow or fail. The README warns about 404s from blob expiration, so this is not a hypothetical. Also, the service is rate-limited and crowded, which makes it unsuitable for large-scale CI fleets that pull hundreds of images simultaneously. The whitelist policy may block certain images or users, though the README does not specify the criteria. For users outside China, the mirror offers no benefit; the official registries are likely faster. For users who need the absolute latest tag immediately, the 1-hour manifest cache is a dealbreaker. The README is honest about these limits, which is rare. The project is best seen as a convenience accelerator for interactive pulls and small-to-medium workloads, not as a reliable registry replacement.

Editorial conclusion

Adopt it if you are in mainland China and need faster pulls from gcr, ghcr, quay, registry.k8s.io, or mcr, and you can tolerate a public, rate-limited service with a 30-day cache. Do not adopt it if you require guaranteed availability, need images older than 30 days without re-sync, or cannot accept the risk of 404s from expired blobs. Before using it in production, verify the current whitelist and rate-limit policy in issue #2328, test your specific image with a pinned @sha256 digest, and have a fallback plan for the 01:00 to 07:00 Beijing time window when the service is less congested.

Official sources

  1. Official README
  2. Project repository
Community notes

Community notes