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,369 stars1,588 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 3 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 November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • DaoCloud/public-image-mirror15,369 ★ · +623
Star history
Repository2026-07-312026-11-14
DaoCloud/public-image-mirror14.7k15.4k

623 Stars in the last 106 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial 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, then explicit version tags, and only last a mutable tag such as latest, because after such a tag changes the mirror serves the old data and re-syncs in the background. This lazy design 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.

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.

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. This repository's 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, schedule pulls in the 01:00 to 07:00 Beijing time window when the service is less congested, and have a fallback plan for other hours.

Frequently asked questions

How do I use DaoCloud's image mirror?

Prefix the image path with the mirror host. An image from the default registry under the library namespace is pulled by putting the mirror in front of the whole path. The alternative is to substitute the registry host using one of eleven mirror-specific hostnames, a table that the documentation marks as manually configured and recommends against.

Why do I get a 404 pulling from the mirror?

The documentation describes it as a possible result. Content is cached for thirty days, manifests for one hour and blobs in memory for one minute, and it notes that during that minute, if a blob reaches the thirty day limit and is deleted, the request returns a 404. So a not-found from the mirror can be a race inside the service rather than a missing image.

How do I configure the mirror for Docker and Podman?

For Docker, add the mirror host for the default registry to the registry-mirrors list in the daemon configuration, and the document warns against configuring other sources there because content at each site differs. For Podman, add per-registry mirror entries in the registries configuration file, which supports the same kind of prefix substitution for non-default registries.

Does the mirror store my images permanently?

It is a mirror of the upstream registries rather than a private store. Cached content is kept for thirty days and then re-synchronised, so nothing is permanent, and all content hashes are kept identical to the source using a lazy loading approach. The synchronisation queue page retains only an hour of records.

Official sources

  1. Official README
  2. Project repository
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/daocloud-public-image-mirror.svg)](https://hysenlabs.com/projects/daocloud-public-image-mirror)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/daocloud-public-image-mirror.svg)](https://hysenlabs.com/projects/daocloud-public-image-mirror)

Was this useful?