Harbor Pull-Based Replication: Mirror Images to Edge Registries Without Touching CI
Harbor's pull-based replication lets regional registries fetch images from a central Harbor on a schedule, so CI publishes once and every cluster pulls locally. Here's how the policies work and where the pitfalls are.
29 Jul 2025, 17:03 UTC

Your CI pipeline publishes an image to a central registry in one region, and then every cluster in three other regions pulls it across a WAN link on every deploy. Deploys are slow, the link bill is ugly, and a partition between regions means nobody can roll out at all. Harbor's pull-based replication solves this without changing a single pipeline: the destination registry fetches what it needs, on your schedule, from the source.
The thesis is simple: let CI publish once to a central Harbor, and let regional or edge Harbor instances pull artifacts toward themselves using replication policies. Consumers always pull locally, and the promotion logic lives in the registry rather than in your build scripts.
What pull-based replication actually is
Harbor replication comes in two flavors. Push-based replication sends artifacts from the local instance to a remote endpoint. Pull-based replication does the opposite: the local instance acts as the initiator and fetches artifacts from a source registry into one of its own projects. The source can be another Harbor instance, Docker Hub, or a supported cloud registry such as ECR, ACR, or GCR, via Harbor's replication adapters.
A replication policy binds together four things:
- A registry endpoint — the remote registry URL plus credentials, configured once under Registries and reused across policies.
- Filters — name, tag, and label patterns, so you mirror only the repositories and tags you care about instead of the entire source.
- A trigger mode — manual, scheduled (cron), or event-based, where supported.
- Destination and options — the local target project, bandwidth/concurrency limits, and whether deletions at the source should propagate.
Replication copies OCI artifacts — container images, Helm charts stored as OCI artifacts, and other types your Harbor version supports — preserving tags. It does not copy Harbor-local configuration: project quotas, RBAC, robot accounts, and retention policies are per-instance and must be managed separately, typically through Terraform or your config management.
A worked example: mirroring production images to an edge site
Say your central Harbor at harbor-central.example.com hosts payments/api, and an edge Harbor at harbor-edge-1.example.com should hold a mirror of everything tagged release-*. On the edge instance, as a Harbor system admin:
- Under Administration → Registries, create an endpoint pointing at
https://harbor-central.example.comwith a robot account or service credential that has pull rights on the source project. Use the Test Connection button before saving. - Under the destination project (create
paymentson the edge instance first), open Replications → New Replication Rule. - Set Replication mode to Pull-based, pick the endpoint you just created, and set the source resource filter: name
payments/api, tagrelease-*. - Set the trigger to Scheduled with a cron expression such as
0 */2 * * *(every two hours), or Manual while you are validating. - Leave deletion mirroring off initially, and set a bandwidth cap if the WAN link is shared.
Run the policy manually once, then verify: the payments/api repository should appear in the edge project with the matching release-* tags, and the manifest digests should match the source. You can confirm digests from any machine with registry access:
crane digest harbor-edge-1.example.com/payments/api:release-1.4.2
crane digest harbor-central.example.com/payments/api:release-1.4.2Both commands should print the same sha256: digest. (docker manifest inspect works too if you don't have crane.) If the digests match, the edge copy is byte-identical and any image-signing or SBOM attestations carried as OCI artifacts remain valid.
Diagnosing partial failures
Replication runs as jobs in Harbor's jobservice. Each policy execution fans out into per-artifact tasks, and each task has its own status and log, visible under the policy's Executions view in the UI or via the API at /api/v2.0/replication/executions. This granularity matters: a policy covering 200 repositories might succeed for 197 and fail for 3 because of an expired source credential on one namespace or a repository that exceeds the destination project's quota. The execution view shows exactly which artifacts failed and why, and re-running the policy only re-attempts what's missing — replication is incremental, comparing digests rather than re-copying everything.
Two operational knobs deserve attention on large syncs. The bandwidth limit on the policy throttles transfer so a first-time mirror of a large project doesn't saturate the link. And the jobservice's worker count controls how many replication tasks run concurrently; if you see the source registry returning 429s or timeouts during big syncs, reduce concurrency rather than retrying harder.
Trade-offs and limitations
Event-based triggers sound like real-time promotion, but they depend on connectivity between the source and destination. During a network partition, events are delayed or lost and the instances drift. Treat replication as eventually consistent: for promotion workflows where correctness matters, gate deploys on the digest existing in the local registry (the crane digest check above works as a pipeline step) rather than assuming the sync already happened.
Adapter support also varies. Not every source/target pair is supported in every Harbor version, and some adapters have feature gaps (for example, around deletion mirroring or certain artifact types). Check the replication adapter documentation for your deployed Harbor version before designing around a specific pair.
Finally, remember the configuration boundary: replication gives you identical artifacts, not identical governance. If your central instance enforces retention or vulnerability-scan gates, you need equivalent policies on each edge instance, applied separately.
Where to start
Pick one low-risk repository, create a pull-based policy with a narrow tag filter on a non-production Harbor instance, and run it manually. Verify the digests match, watch the per-task logs in the execution view, and then widen the filter and add a schedule. Once you trust the mechanics, the pattern scales cleanly: one central publish, N local mirrors, and deploys that never wait on a cross-region pull again.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.