beyond Docker Hub
Docker Hub was the default answer for years to the question of where images get stored, yet rate limits, cost and compliance requirements are increasingly pushing teams toward alternative container registries. GitLab, GitHub, Amazon ECR and self hosted Harbor offer different answers to the same question, which registry fits which situation.
Table of Contents
- 1. Why Docker Hub alone no longer suffices for every team
- 2. GitLab Container Registry: a registry right next to the code
- 3. GitHub Container Registry: tight integration with Actions
- 4. Amazon ECR: a registry inside your own cloud infrastructure
- 5. Harbor: self hosted with enterprise features
- 6. Pull-through mirroring against rate limits
- 7. Migrating away from Docker Hub in practice
- 8. Common mistakes when choosing a registry
- 9. Alternative container registries compared side by side
- 10. Summary
- 11. FAQ
1. Why Docker Hub alone no longer suffices for every team
Docker Hub was the de facto standard registry for years because it was easy to use and most official base images lived there. Since the introduction of strict rate limits for anonymous and unauthenticated pulls, however, many CI pipelines regularly hit limits, especially when several parallel jobs on the same runner pool share an IP address. Alternative container registries solve this problem either by offering their own, higher limits or by billing in a completely different way.
Besides rate limits, compliance requirements also push teams toward alternative container registries. Companies with strict data residency requirements often do not want images stored with an external SaaS provider, preferring their own cloud region or a fully self hosted solution. Integration with existing tooling matters too: a registry sitting right next to the source code repository considerably simplifies access rights and audit trails compared to a completely separate, externally hosted solution.
The choice among the various alternative container registries depends strongly on the existing toolchain context. A team already using GitLab for source code and CI typically benefits most from the integrated GitLab registry, while a team with AWS heavy infrastructure tends toward Amazon ECR. The following sections go into the concrete properties of the most important alternatives.
2. GitLab Container Registry: a registry right next to the code
The GitLab Container Registry is often the most obvious choice among alternative container registries for teams already using GitLab for source code management and CI/CD. Every project automatically gets its own registry namespace, access rights directly follow project and group permissions, and CI jobs authenticate without additional secrets through the built in CI_REGISTRY_PASSWORD variable.
A practical advantage of this alternative container registry is its tight coupling with retention policies: GitLab lets you automatically delete old, unused image tags per project according to configurable rules, for example all tags older than 90 days except the last five. That prevents uncontrolled registry growth without needing to maintain a separate cleanup script.
# Authenticate and push to the GitLab Container Registry from CI
echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
# Registry cleanup policy is configured per project (Settings > Packages & Registries)
# Example: keep the 5 most recent tags, remove anything older than 90 days
3. GitHub Container Registry: tight integration with Actions
The GitHub Container Registry, GHCR for short, follows an approach similar to GitLab's but is tailored to the GitHub ecosystem. As an alternative container registry, GHCR scores mainly through seamless integration into GitHub Actions via the built in GITHUB_TOKEN, which grants push and pull rights for the respective repository without separate secrets management. Images can also be linked directly to a GitHub repository, so users can navigate straight from the source code to the available container versions.
For open source projects, GHCR is particularly attractive as an alternative container registry, because public images are provided free of charge and without rate limits for authenticated pulls, a clear difference from Docker Hub's strict anonymous limits. Private repositories are billed by storage and data transfer, which is usually cheaper for smaller teams than a dedicated Docker Hub Pro license.
# .github/workflows/build.yml -- push to GHCR using the built-in token
name: Build and push
on: [push]
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build and push
run: |
docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
4. Amazon ECR: a registry inside your own cloud infrastructure
Amazon Elastic Container Registry is the obvious choice among alternative container registries when the application runs in AWS anyway, for example on ECS, EKS or Lambda. The decisive advantage: data transfer between ECR and other AWS services in the same region is free and considerably faster than pulling from an external registry over the public internet, which becomes noticeable especially with frequent deployments.
Security wise, what matters with this alternative container registry is its deep integration with IAM: access rights at the repository level can be precisely controlled through IAM policies, without managing separate registry credentials. ECR also offers integrated vulnerability scanning based on Amazon Inspector, which automatically checks for known vulnerabilities on every push, without integrating an external scanning tool into the pipeline.
# Authenticate to Amazon ECR and push an image
aws ecr get-login-password --region eu-central-1 \
| docker login --username AWS --password-stdin 123456789012.dkr.ecr.eu-central-1.amazonaws.com
docker build -t myapp .
docker tag myapp:latest 123456789012.dkr.ecr.eu-central-1.amazonaws.com/myapp:1.4.2
docker push 123456789012.dkr.ecr.eu-central-1.amazonaws.com/myapp:1.4.2
# Vulnerability scan results are available via the AWS CLI
aws ecr describe-image-scan-findings --repository-name myapp --image-id imageTag=1.4.2
5. Harbor: self hosted with enterprise features
Harbor is a CNCF graduated project and the most common choice among alternative container registries when a team needs a fully self hosted solution with enterprise features, for example for data residency or air gap reasons. Harbor comes with built in vulnerability scanning through Trivy, role based access control, image signing with Notary, and a replication feature that automatically synchronizes images between multiple Harbor instances or into external registries.
Operating Harbor as an alternative container registry requires taking on infrastructure responsibility of your own, though: updates, backups and scaling rest entirely with your own team, unlike the fully managed offerings from GitLab, GitHub or AWS. For organizations with strict compliance requirements, for example in finance or healthcare, this extra effort often outweighs the benefits of a managed solution, because Harbor offers full control over storage location and access.
6. Pull-through mirroring against rate limits
Not every team has to move away from Docker Hub entirely to make sensible use of alternative container registries. Pull-through caching mirrors solve the rate limit problem without changing existing image references in code: a mirror such as the one offered by Amazon ECR, or a self hosted Harbor instance with proxy cache functionality, intercepts pulls for Docker Hub images, caches them, and serves subsequent requests from its own cache, without hitting Docker Hub's limits again.
This mirror strategy among alternative container registries fits especially well for teams with many CI runs that constantly pull the same base images such as node, php or mysql. The first pull of an image still goes against Docker Hub, every subsequent pull within the cache validity window comes from the own, unlimited mirror.
# Harbor pull-through cache configuration (project as a proxy cache project)
# In Harbor UI: Projects > New Project > Proxy Cache > docker.io
# Then reference images through the Harbor proxy instead of Docker Hub directly:
# BEFORE: direct pull, subject to Docker Hub rate limits
# FROM node:20-alpine
# AFTER: pull through Harbor's cached proxy project
# FROM harbor.example.com/dockerhub-proxy/library/node:20-alpine
7. Migrating away from Docker Hub in practice
Switching to alternative container registries does not have to happen as a one time big bang step. A proven approach starts by copying all actively used images to the new registry, while Docker Hub remains reachable in parallel as a fallback. Tools such as crane copy or skopeo copy transfer images directly between registries, without a local cache, and can be packaged into a one time migration script.
After the initial copy, CI configurations and Dockerfiles are gradually switched over to the new alternative container registry, project by project rather than in a single risky step. Only once all production references have been switched and an observation period of a few weeks has passed without issues is the old Docker Hub reference finally removed.
#!/usr/bin/env bash
# migrate-to-alternative-registry.sh -- copy images from Docker Hub to GHCR
set -euo pipefail
IMAGES=("myorg/myapp:1.4.0" "myorg/myapp:1.4.1" "myorg/myapp:1.4.2")
TARGET="ghcr.io/myorg"
for image in "${IMAGES[@]}"; do
echo "[migrate] Copying docker.io/${image} -> ${TARGET}/${image#*/}"
crane copy "docker.io/${image}" "${TARGET}/${image#*/}"
done
echo "[migrate] Done. Update Dockerfiles and CI configs to reference ${TARGET}."
8. Common mistakes when choosing a registry
The most common mistake when choosing alternative container registries is migrating purely for cost reasons, without considering the operational responsibility involved. A team switching from a fully managed Docker Hub solution to a self hosted Harbor instance also takes on operational effort for updates, backups and availability that previously rested entirely with an external provider.
# WRONG: hardcoding a single registry host everywhere, no abstraction
FROM docker.io/library/node:20-alpine
# RIGHT: parametrize the registry host, migration becomes a one-line change
ARG REGISTRY_HOST=docker.io/library
FROM ${REGISTRY_HOST}/node:20-alpine
A second widespread mistake is hardcoding registry references in code instead of keeping them parametrizable. If every Dockerfile and every CI configuration hardcodes the registry URL, a later switch between alternative container registries turns into a laborious search and replace operation across the entire codebase, instead of a single configuration change.
9. Alternative container registries compared side by side
The following table compares the most important alternative container registries against practically relevant criteria.
| Registry | Best suited for | Operating model | Distinguishing feature |
|---|---|---|---|
| GitLab Registry | Teams with GitLab as their source code platform | Fully managed | Automatic retention policies |
| GitHub Container Registry | Open source projects, GitHub Actions | Fully managed | Free public images |
| Amazon ECR | AWS heavy infrastructure | Fully managed | Free transfer within AWS |
| Harbor | Strict compliance, air gapped environments | Self hosted | Full control, own operational effort |
| Docker Hub | Small projects, official base images | Fully managed | Strict rate limits without a subscription |
The choice among alternative container registries is rarely a pure feature decision, it depends strongly on which platform a team already uses for source code and CI. A pragmatic intermediate step for many teams is a pull-through mirror, which solves the rate limit problem immediately without forcing a full migration.
Mironsoft
Registry strategy, Docker migrations and container infrastructure
Finding the right registry strategy?
We analyze your current Docker Hub dependency, plan the migration to a suitable alternative container registry, and set up pull-through mirrors where a full migration is not necessary.
Registry selection
Choosing the right alternative based on existing toolchain and compliance
Migration plan
Guiding the gradual switch of Dockerfiles and CI configurations
Mirror setup
Pull-through caching against rate limits without a full migration
10. Summary
Alternative container registries solve concrete problems that Docker Hub alone no longer covers for many teams: rate limits under heavy CI load, compliance requirements around data residency, and the desire for tighter integration with existing source code and CI platforms. GitLab Registry and GitHub Container Registry suit teams already using the respective platform, Amazon ECR fits AWS heavy infrastructures, and Harbor suits organizations with strict compliance requirements and their own operational capacity.
For teams that do not want a complete switch, a pull-through mirror is the most pragmatic solution: it defuses the rate limit problem without fundamentally changing existing image references and processes. What matters in any migration is keeping registry references parametrizable from the start, so a later switch does not require a laborious search and replace operation across the entire codebase.
Alternative container registries — the essentials at a glance
Platform aligned choice
GitLab Registry or GHCR fit best with the source code platform already in use.
Cloud native choice
Amazon ECR saves cost and latency for AWS heavy infrastructure through free internal transfer.
Compliance choice
Harbor offers full control for strict data residency requirements, with its own operational effort.
Pull-through mirroring
Solves rate limit problems without a full migration, ideal as a first pragmatic step.