Skip to content
Vladimir Chavkov
Go back

Harbor: Enterprise Container Registry Complete Guide

Edit page

Harbor: Enterprise Container Registry Complete Guide

Harbor is an open-source, cloud-native container registry that stores, signs, and scans container images and Helm charts. Graduated from the CNCF, Harbor adds enterprise features like vulnerability scanning, content trust, replication, RBAC, and audit logging on top of the Docker registry. This guide covers Harbor deployment, configuration, and production operations.

What is Harbor?

Harbor extends the Docker registry with enterprise capabilities:

Key Features

  1. Vulnerability Scanning: Integrated Trivy scanning for all images
  2. Content Trust: Image signing with Cosign and Notation
  3. RBAC: Project-level role-based access control with LDAP/OIDC
  4. Replication: Image replication across registries (push/pull)
  5. Proxy Cache: Cache remote registries (Docker Hub, GCR, ECR)
  6. Helm Charts: OCI-native Helm chart repository
  7. Quota Management: Per-project storage quotas
  8. Audit Logging: Full audit trail for compliance

Harbor vs. Other Container Registries

FeatureHarborDocker HubQuayGitLab CRNexusACR/ECR/GCR
CostFree/OSSFreemiumFreemiumIncludedFreemiumPay-per-use
Self-HostedYesNoYesYesYesNo
Vulnerability ScanTrivyDocker ScoutClairTrivyLimitedBuilt-in
Content TrustCosign/NotationNotaryNoNoNoSigstore
ReplicationYesNoYesNoYesNo
Proxy CacheYesNoNoYesYesNo
RBACProjectsOrgsTeamsGroupsRolesIAM
Helm ChartsOCI nativeYesNoYesYesYes
OCI ArtifactsYesYesYesYesPartialYes
QuotasYesPlansPlansPlansYesAccount-level
HA SupportYesN/AYesYesYesN/A
LicenseApache 2.0ProprietaryVariesMITVariousProprietary

Architecture

┌──────────────────────────────────────────────────────────┐
│ Harbor Components │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ Portal │ │ Core │ │ Job │ │ Trivy │ │
│ │ (Nginx) │──│ Service │──│ Service │──│Scanner │ │
│ │ Web UI │ │ API │ │ Async │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────┘ │
│ │ │ │ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Registry │ │PostgreSQL│ │ Redis │ │
│ │ (Docker) │ │ (DB) │ │ (Cache) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │
│ ┌──────────────────────────────────────┐ │
│ │ Storage Backend │ │
│ │ S3 | GCS | Azure | Swift | Local │ │
│ └──────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘

Installation

Helm on Kubernetes

Terminal window
# Add Harbor Helm repo
helm repo add harbor https://helm.goharbor.io
helm repo update
# Create namespace
kubectl create namespace harbor
harbor-values.yaml
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: registry.example.com
className: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
externalURL: https://registry.example.com
persistence:
enabled: true
persistentVolumeClaim:
registry:
storageClass: fast-ssd
size: 200Gi
database:
storageClass: fast-ssd
size: 10Gi
redis:
storageClass: fast-ssd
size: 5Gi
trivy:
storageClass: fast-ssd
size: 10Gi
imageChartStorage:
type: s3
s3:
region: eu-west-1
bucket: harbor-registry-storage
accesskey: <ACCESS_KEY>
secretkey: <SECRET_KEY>
harborAdminPassword: <ADMIN_PASSWORD>
database:
type: internal
internal:
resources:
requests:
cpu: 500m
memory: 512Mi
redis:
type: internal
trivy:
enabled: true
gitHubToken: <GITHUB_TOKEN>
severity: "HIGH,CRITICAL"
autoRefresh: true
core:
replicas: 2
resources:
requests:
cpu: 500m
memory: 512Mi
jobservice:
replicas: 2
resources:
requests:
cpu: 500m
memory: 512Mi
registry:
replicas: 2
resources:
requests:
cpu: 500m
memory: 512Mi
portal:
replicas: 2
metrics:
enabled: true
serviceMonitor:
enabled: true
Terminal window
helm install harbor harbor/harbor \
--namespace harbor \
-f harbor-values.yaml

Docker Compose (Offline Installer)

Terminal window
# Download offline installer
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar -xzf harbor-offline-installer-v2.10.0.tgz
cd harbor
# Configure
cp harbor.yml.tmpl harbor.yml
# Edit harbor.yml with your settings
# Install
./install.sh --with-trivy

Configuration

Project Management

Terminal window
# Login to Harbor
docker login registry.example.com
# Create a project via API
curl -X POST https://registry.example.com/api/v2.0/projects \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"project_name": "production",
"public": false,
"storage_limit": 107374182400,
"metadata": {
"auto_scan": "true",
"prevent_vul": "true",
"severity": "critical"
}
}'

LDAP/OIDC Integration

# harbor.yml OIDC configuration
auth_mode: oidc_auth
oidc_name: "Keycloak"
oidc_endpoint: "https://keycloak.example.com/realms/harbor"
oidc_client_id: "harbor"
oidc_client_secret: "<CLIENT_SECRET>"
oidc_groups_claim: "groups"
oidc_admin_group: "harbor-admins"
oidc_scope: "openid,profile,email,groups"
oidc_auto_onboard: true
oidc_user_claim: "preferred_username"

Replication Rules

Terminal window
# Create replication endpoint
curl -X POST https://registry.example.com/api/v2.0/registries \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "docker-hub",
"type": "docker-hub",
"url": "https://hub.docker.com",
"credential": {
"type": "basic",
"access_key": "username",
"access_secret": "password"
}
}'
# Create pull-based replication rule
curl -X POST https://registry.example.com/api/v2.0/replication/policies \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "replicate-from-hub",
"src_registry": {"id": 1},
"dest_namespace": "library",
"filters": [
{"type": "name", "value": "nginx"},
{"type": "tag", "value": "1.25*"}
],
"trigger": {
"type": "scheduled",
"trigger_settings": {"cron": "0 0 * * *"}
},
"enabled": true
}'

Proxy Cache

Terminal window
# Create proxy cache project
curl -X POST https://registry.example.com/api/v2.0/projects \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"project_name": "dockerhub-proxy",
"registry_id": 1,
"public": true
}'
Terminal window
# Pull through proxy cache
docker pull registry.example.com/dockerhub-proxy/library/nginx:1.25

Robot Accounts for CI/CD

Terminal window
# Create robot account
curl -X POST https://registry.example.com/api/v2.0/robots \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "ci-pipeline",
"duration": -1,
"level": "project",
"permissions": [
{
"namespace": "production",
"kind": "project",
"access": [
{"resource": "repository", "action": "push"},
{"resource": "repository", "action": "pull"},
{"resource": "artifact", "action": "read"},
{"resource": "scan", "action": "create"}
]
}
]
}'

Image Scanning and Security

Automatic Scanning

Terminal window
# Enable auto-scan on push (project level)
curl -X PUT https://registry.example.com/api/v2.0/projects/1 \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"metadata": {
"auto_scan": "true",
"prevent_vul": "true",
"severity": "critical"
}
}'
# Manually scan an artifact
curl -X POST https://registry.example.com/api/v2.0/projects/production/repositories/myapp/artifacts/sha256:abc123/scan \
-u "admin:Harbor12345"
# Get scan results
curl https://registry.example.com/api/v2.0/projects/production/repositories/myapp/artifacts/sha256:abc123/additions/vulnerabilities \
-u "admin:Harbor12345"

Image Signing with Cosign

Terminal window
# Generate key pair
cosign generate-key-pair
# Sign an image
cosign sign --key cosign.key registry.example.com/production/myapp:v1.0
# Verify signature
cosign verify --key cosign.pub registry.example.com/production/myapp:v1.0
# Configure Harbor to require signed images
# Via project settings: enable "Content Trust" with Cosign

Garbage Collection

Terminal window
# Trigger garbage collection via API
curl -X POST https://registry.example.com/api/v2.0/system/gc/schedule \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"schedule": {
"type": "Weekly",
"cron": "0 0 0 * * 0"
},
"parameters": {
"delete_untagged": true,
"dry_run": false
}
}'

Monitoring

Prometheus Metrics

# Harbor ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: harbor
namespace: harbor
spec:
selector:
matchLabels:
app: harbor
endpoints:
- port: metrics
interval: 30s

Key Metrics

MetricDescription
harbor_project_totalTotal number of projects
harbor_repository_totalTotal number of repositories
harbor_artifact_pulledNumber of image pulls
harbor_artifact_pushedNumber of image pushes
harbor_quotas_usage_bytesStorage usage per project
harbor_system_infoSystem health information

Production Best Practices

Checklist


Secure Your Container Supply Chain

Building a secure container registry requires expertise in image scanning, signing, RBAC, and registry operations. At chavkov.com, I deliver hands-on Harbor and container security training for production environments.

Contact me to discuss training options for your team.


Edit page
Share this post on:

Previous Post
Trivy: Complete Container and Infrastructure Security Scanner Guide
Next Post
LocalStack: Complete AWS Local Development and Testing Guide