How to export your data from Docker Hub

Docker Hub exposes repository and tag listings through its API, and images can be copied out over the registry API with Skopeo or Harbor replication. This page covers what exports, what does not, the pull-limit impact of a bulk copy, and how to verify the result before renewal.

On this page

Export your Docker Hub data before the contract ends

When a renewal, a pricing change or a residency requirement forces images out of Docker Hub, the core content can move. Repositories, tags and image content can be listed and copied over documented APIs and the registry protocol, while account settings, team membership and some metadata must be recreated by hand. Start by inventorying what your namespaces actually hold: list repositories through the namespace-scoped routes of the Docker Hub API reference, then list tags per repository. Organization access tokens only work on those namespace-scoped routes, so an export script built around personal credentials will behave differently from one built around an organization token. Confirm which token type your automation will use before you write it.

The copy itself has two practical paths. Skopeo can copy or sync images, including manifests, layers and signatures, from Docker Hub to another registry or to a local directory, which suits air-gapped transfers and one-off moves. Harbor pull-based replication can do the same from inside your own environment, with name and tag filters and an optional bandwidth limit, and it keeps the target registry in step on a schedule. Pick one path per repository and record which tags were copied, so you can reconcile the target against the source before the contract ends.

The main caveat is pull limits. Every architecture of a multi-architecture image counts as a separate pull, so a bulk export of multi-architecture tags can consume several pulls per tag on an account with a pull limit. Docker's documented limits apply per IP address or subnet for unauthenticated pulls and per account for personal plans, so run exports from an authenticated, well-understood network and check your current plan's allowance in Docker's pull documentation before scheduling a large job. Plan the export window early, and ask your Docker account team to confirm which limits apply to your plan during the transition.

What you can export from Docker Hub and how

This table maps each kind of Docker Hub data to the method that exports it, the output you get and the limits that apply. Read it as a checklist: confirm each row against your own account before starting a bulk export. The main takeaway is that tag listing is API work, while image content moves through the registry API, and multi-architecture tags cost more pulls than their tag count suggests.

Data typeExport methodOutput and limits
Repository listDocker Hub API on /v2/namespaces/{namespace}/repositories/, paged with a tokenJSON metadata per repository; only namespace-scoped routes work with organization access tokens
Tags per repositoryDocker Hub API on /v2/namespaces/{namespace}/repositories/{repository}/tagsJSON list of tag names and metadata; confirm pagination limits in the API reference
Image manifests and layersSkopeo copy or sync to a registry or local directoryLayers and manifests copied as OCI content; each pull counts against account limits
Multi-architecture indexesSkopeo copy with all architectures, or sync with the architecture filters you needEach architecture counts as a separate pull, so a multi-architecture tag uses several pulls
Signatures and attestationsSkopeo copy, which carries signatures with the imageConfirm with the destination registry that signatures are stored and verifiable after import
Pull limit impactPlan the export window against per-IP and per-account pull limitsPulls are counted per architecture, so run exports in batches and check remaining quota first
Organization access tokensUse them only on namespace-scoped API routesOther routes need a different credential; test each route before scripting the export

Choosing between Skopeo and Harbor pull replication

Skopeo is a command-line tool that copies images between registries or into a local directory without needing a container runtime or elevated privileges. It fits a bounded export: a list of repositories that someone runs once or a few times, with the output going to a target registry, a file tree or a transfer host. The Skopeo README describes its sync command for mirroring a repository to another registry or to a directory, which covers the air-gapped case where media is carried across a boundary.

  • Destination flexibility: Skopeo can write to another registry, including a Harbor project, or to a directory for offline transfer, so it does not require a Harbor instance to exist first.
  • Low setup: A shell script, a credentials file and a tag list are enough to start. There is no service to install, patch or back up.
  • Manual control of scope: Filters live in your script, so the team must write and review the logic for tag selection and multi-architecture handling.
  • No built-in scheduling or audit trail: Retries, bandwidth caps, run history and alerts must come from cron, CI or your own logging.
  • Credential handling: Source credentials must be stored and rotated by the team running the script, which matters when the export uses organization access tokens.

Before running a bulk copy, confirm which pull limits apply to your source account, since each architecture of a multi-architecture image counts as a separate pull. Check the copy result for each tag in a test run first.

What does not export and how to recreate it

The API and replication paths move images, tags and repository listings, but several account-level items sit outside them. Each card below names one item, the workaround, and the point where you should confirm current scope in Docker's documentation before you plan the cutover.

User accounts and team membership

Docker Hub users, teams and organization memberships are account records, not registry content, so a pull or replication job will not copy them. Build an inventory of who holds push, pull and admin rights on each namespace before the export. In the destination, recreate those rights as Harbor projects with role-based access control, and map each Docker Hub team to a Harbor group or OIDC claim where your identity provider supports it. Confirm the current user and team data scope with Docker's documentation before you assume anything is exportable.

Access tokens and credentials

Personal access tokens and organization access tokens are bound to Docker Hub and cannot be transferred. Organization access tokens only work on namespace-scoped API routes, so scripts that depend on them will stop working once you leave. Issue new robot or service accounts in Harbor, store their secrets in your secrets manager, and update CI variables and Kubernetes image pull secrets before cutover. Treat any token that appears in old pipeline logs as compromised and rotate it.

Webhooks and automated build settings

Webhooks, automated builds and their linked source repository settings are Docker Hub configuration, so they do not follow the image data. Export a list of each repository's webhook targets and build rules from the console or the API while your account is still active. Recreate the equivalent in your CI system, or in Harbor webhook policies for push and scan events. Note that Harbor blocks webhooks to internal network addresses by default in v2.15.3, so an internal receiver needs an explicit allowance and a review.

Repository descriptions and README content

Repository short descriptions, full overview text and README markdown are stored as Docker Hub metadata and are not part of the image manifest or its layers. Copy them by hand or script a save of the overview text from the console or API into your source repository. In Harbor, place the text in your Git repository or in a project-level document, because Harbor's project pages do not replace Docker Hub's overview. Images that carry OCI annotations keep their labels, so check those labels before you assume metadata moved.

Billing history and plan records

Invoices, subscription history, payment methods and seat counts are financial records held by Docker, not registry data. Download the invoices and plan documents you need for finance, audit or tax records before you cancel, and note the renewal date so you do not pay for an unused seat. Recreating this history is not possible, so accept the loss of the records inside Docker Hub and keep your own copies. Ask Docker which billing exports are available to your account role before the final invoice closes.

Pull statistics and download counts

Pull counts, download history and usage graphs are analytics data that Docker Hub reports per repository. They do not copy into a new registry, and Harbor records its own pull activity only from the point it starts serving traffic. Record the current totals for any repository your users track, and set up audit logs and metrics in Harbor so future activity is measurable. Accept that the historical series will end at the cutover date.

Run a complete Docker Hub export in order

This sequence produces a complete, verified copy of every repository, tag and architecture you own on Docker Hub, with a digest record that proves the copy matches the source. Work through it once for a full export and again for any final delta before cutover.

  1. Create a scoped read-only access token

    Start by creating a Docker Hub access token with read-only permissions for the namespace you are exporting, using an account that owns or administers those repositories. Store the token in your secrets manager, not in shell history or CI variables visible to the whole team. Organization access tokens only work on namespace-scoped API routes, so confirm you are querying the correct organization namespace before you go further. The output is a working token that returns your repository list without errors.

  2. Inventory namespaces and repositories through the API

    Call the namespace-scoped repository route in the Docker Hub API reference to list every repository in each namespace in scope, paging through all results. Save the output as a file that lists namespace, repository name, visibility and last-updated date. Ask the account owner whether any repositories are private, archived or owned by other teams, because these often get missed in a manual list. The output is a complete repository inventory that you and the owner have reviewed.

  3. Record tags and architectures for each repository

    For each repository in the inventory, call the namespace-scoped tags route and capture every tag name along with its manifest digest. For multi-architecture tags, record each platform entry, such as linux/amd64 and linux/arm64, so you know what the copy must contain. Flag tags that point to the same digest, since copying by digest avoids pulling the same content twice. The output is a tag manifest file that serves as the expected result for verification.

  4. Schedule the bulk copy around pull limits

    Docker Hub counts each architecture of a multi-architecture image as a separate pull, so a bulk export of multi-architecture tags consumes several pulls per tag on accounts with a pull limit. Estimate the total pull count from your tag manifest, then confirm the current limits for your account type in the Docker documentation on pull usage. Schedule the copy in batches, run it from a single authenticated host, and pause between batches if you approach the limit. The output is a written batch plan that the operations owner has approved.

  5. Copy each repository with Skopeo or a replication rule

    Copy each repository to the destination registry with Skopeo, which carries manifests, layers and signatures from one registry to another, or with a Harbor pull-based replication rule filtered by repository name and tag. Authenticate to Docker Hub with the read-only token and push to the destination with a robot account scoped to the target project. Run one batch at a time and log each copy result. The output is a destination registry populated by batch, with a log entry for every repository and tag.

  6. Record digests from the source and destination

    After each batch, list the digest of every tag in the source and in the destination and write both to a comparison file. Digests are content identifiers, so matching digests show the copied manifest is identical to the original, including per-architecture entries. Investigate any tag whose digest differs or is missing, and re-copy it before continuing. The output is a digest comparison file with no unexplained differences.

  7. Verify tags, architectures and signatures

    Compare the destination tag list against the manifest from the tag inventory and confirm that every repository, tag and platform entry is present. Pull a sample of images on each architecture from the destination to confirm they start and run as expected. If images were signed, check that the signatures and any attached artifacts also arrived, since Skopeo and Harbor both carry them when they are included in the copy. The output is a signed-off verification report listing any exceptions and how each was resolved.

  8. Run a final delta copy before cutover

    Repositories keep changing during a long export, so repeat the inventory and tag steps close to the cutover date and copy only tags whose digests changed. Compare the final digest file again and keep the source read-only or frozen for the duration of the last copy if your process allows it. Keep the verified export, digest files and logs in your records. The output is a final digest match across all in-scope repositories, which is the basis for pointing CI and clusters at the new registry.

How pull limits count against a bulk export

Plan the export around Docker Hub's pull budget before you start it, because a bulk pull can exhaust the limit long before the job finishes. Docker Hub limits unauthenticated pulls to 100 per 6 hours per IPv4 address or IPv6 /64 subnet, and Personal accounts to 200 per 6 hours, according to the Docker Hub pull usage and limits documentation. Every architecture of a multi-architecture image counts as a separate pull, so a tag that ships amd64, arm64 and s390x variants can consume several pulls when you fetch it. An export of a repository with many tags across several platforms can therefore spend the budget in a single run, and the remaining tags fail until the window resets. The practical controls are authentication and where the job runs. Pulls made with an authenticated account are counted against that account's limit rather than the anonymous per-IP allowance, so run the export with a dedicated account or organization token and confirm the current limit for that account type with Docker before you rely on it. Keep the export on one host or a small, known set of egress addresses, because the limit follows the source IP or subnet and a fleet of CI runners pulling in parallel will share one budget. Estimate the number of pulls by counting tags multiplied by platforms per tag, and split the work into batches that fit the window. Filter out tags you do not need, since every unnecessary pull draws from the same budget. After the first copy lands in your own environment, avoid repeating the pulls from Docker Hub. If you front Docker Hub with a Harbor proxy cache project, Harbor's documentation says it checks cached images with HEAD requests, and those checks do not trigger the Docker Hub rate limiter, so later runs that revalidate cached content stay within the budget. Confirm this behavior in your own environment with a test pull and a Docker Hub usage check before a production cutover, and record the pull counts for each batch so you can see whether a rerun costs anything.

Verifying the export before you cut over

A bulk export is only finished when the destination matches the source in ways you can prove. The checks below run in parallel where possible and each one should be confirmed against your own repositories, not assumed from a successful copy command.

Match repository and tag counts

Count repositories and tags from the Docker Hub API using namespace-scoped routes, then count the same repositories and tags in Harbor. Run the count per namespace, because organization access tokens only work on those routes. Mismatches usually come from private repositories the export token could not see, or from tags skipped by a name or tag filter in a replication rule. Confirm the counts match for every namespace in scope.

Compare digests per tag and architecture

Counts alone do not prove the content is the same. For each tag, compare the manifest digest at the source with the digest at the destination, and check each platform entry of multi-architecture images separately. A tag that resolves to a different digest after the copy points to a rebuilt or re-tagged image that CI may treat as a new artifact. Record any mismatch with the tag name, platform and digest pair before you move on.

Confirm signatures and referrers

Where images carry signatures, SBOMs or attestations, verify that they arrived and still point at the right image. The OCI Distribution Specification defines a referrers API for this, so check that the destination lists the same referring manifests per digest. Skopeo copies signatures, but confirm that your signing policy still validates against the destination, since an unexpected change can block deployments.

Pull from a clean host

Test the copy the way production will use it. From a host or cluster node with no local image cache and no Docker Hub credentials, pull a sample of images, including one multi-architecture image on each target platform. Use the same registry hostname, pull secret and certificate chain your workloads will use. A pull that works only on the machine that performed the copy does not prove the cutover is ready.

Keep a dated inventory

Write down what was exported, from which namespace, at what time, by which tool and version, and with which digests. Store the inventory outside both registries so it survives a rollback. Keep the record of any excluded repositories and the reason for each exclusion. This inventory is the evidence you will need if a team later asks whether an image existed or changed, and it gives your auditors a starting point for the migration.

Questions buyers ask before exporting from Docker Hub

Can our team export from Docker Hub without outside help?

Yes, most teams with a container platform engineer can run the export themselves, because the tooling is open source and the steps are well documented. The work is mainly inventory, token setup and a repeatable copy job. Effort rises when the estate is large, when images are poorly tagged, or when no one has time to verify the result. Start by listing repositories through the Docker Hub API reference with an organization access token, since those tokens only work on namespace-scoped routes. Then decide whether the team has the time and the on-call coverage to own the copy and its verification.

What makes a Docker Hub export larger or harder?

The main drivers are the number of repositories, the total size of image layers, the number of architectures per image, and how many historical tags you keep. Each architecture of a multi-architecture image is counted as a separate pull by Docker Hub, so a bulk export of multi-architecture tags uses several pulls per tag on accounts with a pull limit. Tag history matters because old tags often point to images nobody uses but that still need copying if policy requires them. Build a spreadsheet of repositories, tag counts and architectures before you estimate effort, and treat untagged or orphaned images as a separate decision.

What do we need in place before the copy starts?

You need four things: a Docker Hub account or organization with read access to the repositories, an access token that can list them, a host that can reach both Docker Hub and your target registry, and a running Harbor instance with projects and credentials set up. The transfer host runs Skopeo or Harbor replication and needs enough disk for staging if you copy through it. Confirm network egress rules, storage capacity on Harbor, and who owns the robot or service accounts used for writes. Check the Skopeo README for the copy commands and the flags your version supports.

How long does a bulk copy take, and what changes the time?

No duration is fixed by the tools, so the honest answer depends on the data. Total image size, the bandwidth between Docker Hub and your transfer host, and the bandwidth between that host and Harbor set the floor. Harbor replication rules can apply a per-task bandwidth limit, which protects other traffic but lengthens the job. Parallelism, retries after transient failures, and the number of architectures also shift the timeline. Ask the implementation partner or your own team to run a pilot on one large repository and one small one, then extrapolate from measured throughput rather than from assumptions.

Do we need a paid Docker plan during the export?

Not always, but pull limits decide the answer. Docker documents that unauthenticated pulls are limited to 100 per 6 hours per IPv4 address or IPv6 /64 subnet, and Personal accounts to 200 per 6 hours. A bulk export from a single host can hit these limits quickly, so authenticate the copy job and spread the work over time if needed. Check the current limits and what your plan includes on Docker's pulls usage page before you schedule the copy. Keep the paid plan until you have verified every tag in Harbor and retired the old pull paths.

Does a Harbor proxy cache avoid pull limits during the export?

A proxy cache helps with ongoing pulls more than with a one-time export. Harbor documents that its proxy cache checks cached images with HEAD requests that do not trigger the Docker Hub rate limiter, but the first fetch of each image still reads from Docker Hub. For the export itself, pulling into Harbor through replication or Skopeo is the direct route. Use the proxy cache afterward for public base images that your clusters pull repeatedly. Confirm the cache behavior against the proxy cache documentation for your Harbor version.

What would an outside implementation partner scope for this export?

DeployOpen plans and implements self-hosted platforms in your own infrastructure, and a Harbor export is a fixed-scope engagement that starts with agreed deliverables and timelines. A typical written scope covers the repository inventory, the copy method for each group of repositories, the verification steps that compare tags, digests and architectures, the Harbor projects and access model, and the cutover plan for CI and cluster pull secrets. Scope also covers backup before any Harbor upgrade and handover documentation. Ask for a written scope with named deliverables, and expect the quote to follow from it rather than from a published price list.

How DeployOpen scopes and delivers a Docker Hub exit

DeployOpen plans and implements self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For a Docker Hub export, we start from a written scope that names the namespaces, repositories and credentials involved, then build and document the transfer so your team can verify and keep the copies.

How we scope

  • Inventory of namespaces, repositories and tags to export, agreed in writing before work starts
  • Decision on who holds organization access tokens and how they are scoped and rotated
  • Pull budget estimate for multi-architecture tags, confirmed against your Docker plan and IP addresses

How we build

  • Export scripts using the Docker Hub API with access tokens to list repositories and tags
  • Skopeo or Harbor pull replication configured to copy every tag and architecture to your registry
  • Verification step comparing source and destination tag and digest lists before cutover

How we hand over

  • Written runbook covering export steps, retry handling and the pull limit behavior observed during the run
  • Documented inventory and digest report delivered with the exported repositories
  • Walkthrough with your platform and security teams on storing and retiring the access tokens used

How we support

  • Fixed-scope engagements with deliverables and timelines agreed in writing before work starts
  • Ongoing support, upgrades and continuous testing available as a retainer after handover
  • Follow-up review of the destination registry settings for backup and upgrade planning

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.