NODED.CLOUD/Blog/Self-Hosted Docker Registry on a VPS

Self-Hosted Docker Registry on a VPS

26 Aug 2026 · Mario Marin

A setup and sizing guide for running Docker Distribution or Harbor as a private registry on a VPS, matched to image storage volume and CI pull frequency to avoid Docker Hub's rate limits and per-seat pricing.

Docker Hub's anonymous pull limits and per-seat pricing on private repos have a way of showing up at the worst time — mid-deploy, mid-incident, mid-demo. Self-hosting a Docker registry on a VPS sidesteps both problems: no rate limiting on your own infrastructure, no per-user tax on private images, and full control over retention and access. This is a sizing and setup guide for a self-hosted docker registry vps running Docker Distribution or Harbor, matched to actual image storage volume and CI pull frequency rather than guesswork.

Why Bother Self-Hosting a Registry

Docker Hub throttles anonymous and free-tier pulls per six-hour window, and that ceiling gets hit fast once a CI pipeline is pulling base images on every build. Private repositories on Hub, GHCR, or most managed registries also bill per seat or per organization member, which scales badly once more than a couple of people or service accounts need pull access. A private docker registry hosting setup on a VPS you control has neither limit — it's your storage, your bandwidth, your uptime to manage.

The tradeoff is operational: you're now responsible for TLS, auth, garbage collection, and backups. For a small-to-mid engineering team or an agency running client CI pipelines, that tradeoff is usually worth it within the first few months, especially once Hub's rate limits start blocking deploys.

Distribution vs Harbor: Picking Your Registry Software

Two realistic options for a self-hosted registry:

  • Docker Distribution (registry:2) — the reference implementation, a single Go binary in a container. Minimal footprint, no UI beyond the API, config via one YAML file. Good fit for a single team or a CI-only registry with no need for RBAC.
  • Harbor — a CNCF project layering a web UI, project-based RBAC, vulnerability scanning (Trivy), image signing, and replication on top of Distribution. Heavier — it's a docker-compose stack of a dozen or so containers (core, portal, registry, database, Redis, job service) — but worth it once you have multiple teams or need audit trails on who pushed what.

If you're not sure, start with plain Distribution behind nginx for TLS termination. It's a smaller thing to operate and you can migrate image data into Harbor later if RBAC and scanning become a requirement.

Sizing the VPS by Storage and Pull Volume

Registry sizing comes down to two numbers: how much image data you're storing (layers add up fast with multiple tags and language runtimes baked in) and how many pulls per hour your CI pipelines generate. Root access on the box supports installing Docker or Harbor directly with no managed-platform layer in the way, which also means no forced feature limits on storage backends or garbage collection schedules.

Use caseTypical registry footprintFit
Solo dev / small team, few repos, nightly buildsUnder 15GB images, low pull volumeVPS I (2GB/1vCPU/20GB)
Small team CI, several services, tagged releases kept15-35GB, moderate pull burstsVPS II (4GB/2vCPU/40GB)
Multi-repo org, Harbor with scanning + Redis + Postgres35-50GB, steady daytime pullsVPS III (8GB/2vCPU/60GB)
Agency or platform team, many client pipelines50-70GB, frequent concurrent pullsVPS IV (16GB/4vCPU/80GB)
Registry as shared infra across several products70-110GB, heavy concurrent CI loadVPS VI (32GB/8vCPU/120GB)

Full specs and current pricing for every tier are on the VPS hosting page. Any tier can take extra storage in 50GB increments, up to 150GB on top of the plan's disk. If your image storage is tracking past that, or you need dedicated disk I/O isolated from other tenants, that's the point to look at dedicated hardware instead.

Docker Registry VPS Setup Walkthrough

For a Distribution-based setup, the shape of it looks like this:

  • Provision the VPS, point a subdomain (e.g. registry.yourdomain.com) at its IPv4 address (plus IPv6 where the location offers it), and issue a TLS cert (Let's Encrypt via certbot or acme.sh).
  • Run registry:2 as a container with a bind-mounted volume for /var/lib/registry — this is your image layer storage, so it should sit on the largest disk you provisioned for.
  • Put nginx or Caddy in front for TLS termination and basic auth (htpasswd) or forward auth to your existing identity provider.
  • Set a garbage collection cron (registry garbage-collect) to reclaim space from untagged/deleted layers — this is the step most self-hosted registries skip and then run out of disk.

For Harbor, the installer script generates a docker-compose.yml from harbor.yml — set the hostname, TLS cert paths, and storage paths there, then install.sh brings up the full stack. Harbor's own Postgres and Redis containers add meaningful RAM overhead versus plain Distribution, which is why Harbor deployments generally want at least the 8GB tier.

Bandwidth and CI Pipeline Fit

A registry that throttles pulls during a deploy defeats the point of self-hosting one. Unmetered symmetric bandwidth on every VPS tier (ports shaped from 100 Mbps on VPS I to 300 Mbps on VPS VI) means CI runners pulling images in parallel never hit a transfer quota — size the tier with port speed in mind once you have several pipelines pulling the same base images concurrently at build start.

Hourly billing is a good match for registries that only need to exist during a pipeline's active hours (a powered-off VPS still bills, so delete it between runs) — for example, a registry spun up for a burst of nightly builds or a temporary CI environment, rather than paying for a 24/7 instance you don't need. Combined with a deploy time of about a minute, that makes standing up a throwaway or scheduled registry instance for CI workloads practical rather than theoretical, without committing to always-on infrastructure for something that only runs a few hours a day.

Security and Operational Notes

A registry holding proprietary images is a target worth locking down properly:

  • Never expose the registry API without TLS and auth — an open registry:2 on port 5000 is a common misconfiguration scanners actively look for.
  • Restrict push access separately from pull access where possible (Harbor's RBAC handles this natively; Distribution needs a proxy-layer auth service or token server for anything beyond basic auth).
  • Back up the image storage volume and any registry metadata/database on a schedule — losing the registry means rebuilding every image from source, which is rarely fast.
  • Every VPS tier ships with always-on 100 Gbps Layer 3/4 DDoS protection, which covers the registry endpoint against volumetric floods without needing a separate mitigation service.

How Noded Can Help

We run our own AS60982, and every VPS tier includes unmetered symmetric bandwidth and 100 Gbps of DDoS protection. Root SSH access and 26 Linux and FreeBSD images mean you install Distribution or Harbor exactly the way you'd run it on bare metal, and with hourly billing, a CI-only registry instance you delete between build windows stops costing you once it is gone (a powered-off VPS still bills). If your image storage is already past what a single VPS comfortably holds, the next step is moving the registry to a dedicated box with dedicated disk I/O instead. Either way, start by sizing against the table above and provision from our VPS hosting page.

FAQ

Is a self-hosted Docker registry actually cheaper than Docker Hub?

For teams with more than a handful of users needing private repo access, yes — Hub's per-seat pricing scales linearly with headcount while a self-hosted registry's cost is tied to VPS size, which scales with storage and pull volume instead of user count.

Do I need Harbor, or is plain Docker Distribution enough?

Plain Distribution is enough for a single team or a CI-only registry with no need for role-based access control. Reach for Harbor once you need per-project permissions, vulnerability scanning, or an audit trail of who pushed what.

How much VPS storage does a Docker registry actually need?

It depends on image count, tag retention policy, and layer reuse — a handful of services with a few kept tags each can fit well under 40GB, while an org keeping many historical releases across multiple services can climb past 200GB. Run garbage collection regularly to keep storage from growing unbounded.

Will CI pulls get throttled on a self-hosted registry VPS?

Not by a data cap — every VPS tier includes unmetered symmetric bandwidth, so concurrent pulls from CI runners never hit a transfer quota or a Docker Hub-style rate limit; throughput is bounded by the plan's port speed (100–300 Mbps).

Can I run the registry only during CI hours to save cost?

Yes — since billing is by the hour, spinning up a registry instance for a scheduled build window and deleting it afterward (restoring images from a backup on the next run) is a realistic way to avoid paying for idle time, particularly for infrequent or scheduled pipelines.

← All posts

Related services

Run this on NODED.CLOUD.

Keep reading

More from the NOC.

22 Oct 2026·Mario Marin

DDoS Protection for Self-Hosted Apps: A Hands-On Guide

What the included 100 Gbps of Layer 3/4 filtering does for a self-hosted VPS, and what stays your job: nginx rate limits with a strict login zone, Nextcloud, Vaultwarden and Synapse limits, CrowdSec or fail2ban, and where a CDN stops.

Read post
01 Sept 2026·Mario Marin

Self-Hosted Error Tracking: GlitchTip on a VPS

A sizing and setup guide for running GlitchTip, the open-source Sentry-compatible error tracker, on a self-hosted VPS — with a look at why teams move off per-event SaaS pricing and keep error data on EU infrastructure.

Read post
25 Aug 2026·Mario Marin

Sizing a VPS for Web Scraping at Scale

A spec-matrix guide to sizing a VPS for web scraping, from plain HTTP crawlers through Playwright/Crawlee crawls up to a dedicated server for sustained multi-instance jobs.

Read post

Like the way we run things? Spin up a server in 60 seconds.