Self-Hosted Container Registry with Harbor (Complete Guide)

self hosted container registry harbor custom-harbor-featured.png

Docker Hub’s free tier has pull-rate limits and no private-network guarantee for where your images physically live — fine for a hobby project, not always fine for a company with compliance requirements or an air-gapped environment. Harbor is a production-grade, self-hosted container registry with built-in vulnerability scanning, role-based access control, and image replication — the CNCF’s answer to “run your own Docker Hub.”

This guide installs Harbor via its Docker Compose-based installer, pushes and pulls an image, enables Trivy scanning, and sets up a scoped robot account for CI use.

Step 1: Why Run a Private Registry

A private registry gives you: control over where images physically live (relevant for compliance or air-gapped deployments), no dependency on a third party’s uptime or rate limits for your own internal images, and — with Harbor specifically — built-in vulnerability scanning so you know what CVEs are sitting in an image before it deploys, not after.

Why run a self-hosted private container registry with Harbor
Step 1: Why Run a Private Registry

Step 2: Prerequisites

Harbor needs Docker and Docker Compose installed on the host, and — critically — a real TLS certificate for its hostname, since Docker refuses to push to an insecure registry by default without extra client-side configuration you don’t want to rely on long-term. Use our Certbot guide or an internal CA if this registry stays inside a private network.

Prerequisites for installing Harbor container registry with TLS
Step 2: Prerequisites

Step 3: Configure harbor.yml

Download the Harbor offline or online installer, extract it, and copy harbor.yml.tmpl to harbor.yml. Set the hostname to your registry’s actual DNS name, and point certificate/private_key at your TLS cert files. Set the initial admin password here too — Harbor uses this only for the very first login.

Configuring Harbor harbor.yml hostname and TLS certificate
Step 3: Configure harbor.yml

Step 4: Run the Installer

./install.sh --with-trivy pulls Harbor’s component images and starts everything via Docker Compose — the --with-trivy flag bundles the vulnerability scanner in from the start rather than needing to add it later. This takes a few minutes; watch for the final success banner before assuming it’s ready.

Running Harbor install.sh with Trivy vulnerability scanner
Step 4: Run the Installer

Step 5: Log In and Create a Project

Browse to https://your-registry-hostname and log in with the admin credentials from harbor.yml. Create a Project — Harbor’s equivalent of a namespace grouping related repositories, with its own access control and settings (public or private, scan-on-push enabled or not).

Creating a project in Harbor container registry UI
Step 5: Log In and Create a Project

Step 6: Push and Pull an Image

From any Docker host: docker login registry.example.com, tag an image with the registry’s hostname and project (docker tag myapp:1.0 registry.example.com/myproj/myapp:1.0), then docker push registry.example.com/myproj/myapp:1.0. Pull it on another host the same way any Docker Hub image would be pulled, just with the full registry hostname prefixed.

Pushing and pulling Docker images to Harbor registry
Step 6: Push and Pull an Image

Step 7: Enable Vulnerability Scanning

With Trivy bundled in, every pushed image can be scanned automatically (enable Automatically scan images on push in the project’s config) or triggered manually from the image’s page in the UI. Review the CVE severity breakdown before promoting an image to production — this is the concrete benefit over a plain registry with no scanning at all.

Enabling Trivy vulnerability scanning on Harbor images
Step 7: Enable Vulnerability Scanning

Step 8: Set Up Robot Accounts for CI

Don’t use your personal admin login in a CI pipeline. Harbor’s Robot Accounts feature (Project → Robot Accounts → New) creates a scoped credential limited to specific actions (push, pull) on a specific project — exactly what a CI/CD pipeline needs, following the same least-privilege principle as the Proxmox and Vault scoped-token guides elsewhere on this site.

Creating Harbor robot account for CI CD pipeline access
Step 8: Set Up Robot Accounts for CI

Command reference

# Install
cp harbor.yml.tmpl harbor.yml
./install.sh --with-trivy

# Push an image
docker login registry.example.com
docker tag myapp:1.0 registry.example.com/myproj/myapp:1.0
docker push registry.example.com/myproj/myapp:1.0

Related tutorials

Terminal screenshots are original illustrations created for Gnome IT Solutions (blog.gnomeitsolutions.com).