Container Registries: GitHub Container Registry vs Docker Hub Basics
Understand what a container registry is and compare Docker Hub against GitHub Container Registry for hosting public and private images.
Netbay Infrastructure Team
Netbay Engineering
On this page
A container image is just a bundle of files plus metadata, but images have to live somewhere both machines and humans can reach. That somewhere is a registry: a service that stores layers, serves them over the Registry HTTP API, and enforces access control. Two registries dominate daily practice — Docker Hub, the default, and GitHub Container Registry (GHCR), which sits inside your GitHub account.
Choosing between them is not a religious question. It is a question about where you already keep code, how you want rate limits to behave, and whether your images should be public or private.
What a Registry Does Under the Hood
When you run docker pull, the client speaks to the registry in a specific dance: it fetches a manifest, which lists the layers by digest, then it fetches each layer blob and verifies its sha256 checksum. A tag like :latest is just a pointer to a manifest. The whole thing is content-addressed, which is why a single blob is only stored once even if several images share it.
# the pull is really this simple at the HTTP level
curl -sI https://registry-1.docker.io/v2/library/nginx/manifests/1.27-alpine
# auth + manifest + blobs = a pull
docker pull nginx:1.27-alpine
docker manifest inspect nginx:1.27-alpineThe Registry v2 API matters because both Docker Hub and GHCR implement it, so pushing and pulling against either feels identical from the client's point of view.
Docker Hub: Familiarity and Rate Limits
Docker Hub is the default because every Docker install points at it. It is fine for public base images and small projects. The catch is anonymous pull rate limits: unauthenticated clients get a modest per-IP budget, and even free authenticated accounts have a ceiling. Public official images are the main reason to keep using it.
# log in once so pulls count against your account, not the anonymous pool
docker login
docker build -t myapp:1.0 .
docker tag myapp:1.0 mydockeruser/myapp:1.0
docker push mydockeruser/myapp:1.0GitHub Container Registry: Tied to Your Repos
GHCR is namespaced under your GitHub account or organization and inherits its permissions. You can build an image and publish it directly from a GitHub Actions workflow, which keeps the entire artifact lifecycle next to the source. Private packages follow repository permissions, and public packages are handy for sharing without paying a separate bill. Pushing to GHCR uses the GitHub token:
echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USER --password-stdin
docker tag myapp:1.0 ghcr.io/$GITHUB_USER/myapp:1.0
docker push ghcr.io/$GITHUB_USER/myapp:1.0The tradeoff is inertia: images published under ghcr.io need a slightly longer pull spec, and org settings can surprise you if package permissions are not turned on.
Which One for Your Workflow
- Public open-source images and official bases: Docker Hub.
- Private or org-scoped images built alongside a GitHub repo: GHCR.
- Fast pull times from nearly any VPS: pick whichever registry you already have credentials for; both are served over CDN-backed infrastructure.
- Self-hosted mirrors are worth it only at serious pull volume; for a single server the public registries are fine.
The pull to a VPS flows the same way from either registry, once you have credentials stored locally.
Takeaway
The registry is your distribution layer, and the choice mostly comes down to where your code already lives. Both work identically from a pulling server: docker pull and docker run just work. Deploy images from either onto a Netbay VPS — spin one up at netbayhosts.in and your CI can push a tag and have the host pull and run it in the same minute.
Keep reading
Follow along on a real VPS
Deploy Linux in under 60 seconds
These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.
Deploy an instance