Table of Contents
In today’s containerized world, managing multiple Docker images securely and efficiently is crucial for organizations of all sizes. As enterprises scale their container deployments, the need for a robust, secure, and feature-rich container registry becomes paramount. Harbor, a CNCF graduated project with over 30,000 GitHub stars, is the most widely adopted open-source cloud native container registry. This comprehensive guide walks you through building a multi-tenant Docker registry with Harbor, covering everything from installation to advanced security configurations.
What is Harbor and Why Choose It?
Harbor is an open source registry that secures artifacts with policies and role-based access control, ensures images are scanned and free from vulnerabilities, and signs images as trusted. Harbor extends the open source Docker Distribution by adding the functionalities usually required by users such as security, identity and management.
VMware open-sourced Harbor in 2016, it joined the CNCF in July 2018, and it graduated in June 2020 — making it the first open-source registry to reach CNCF graduated status. This milestone reflects both its maturity and the strength of its community support.
Key Features That Set Harbor Apart
Harbor distinguishes itself from basic Docker registries and even commercial alternatives through several enterprise-grade capabilities:
- Multi-tenancy Through Projects: Harbor organizes content into projects, with each project getting its own RBAC policies, scan settings, quota limits, and tag retention rules
- Built-in Vulnerability Scanning: Harbor includes scan-on-push policies with pluggable backends including Trivy, Clair, and Anchore that block vulnerable images before deployment
- Image Signing and Content Trust: Harbor supports artifact signing with Cosign and Notation for supply chain security, plus content trust policies that enforce only signed images can be pulled
- Multi-registry Replication: Harbor syncs images across data centers, cloud regions, or hybrid environments with policy-based filters on repositories, tags, and labels
- Comprehensive Access Control: Authentication plugs into LDAP, Active Directory, OIDC providers, or the built-in database
- Robot Accounts for Automation: Robot accounts give CI/CD pipelines non-human access with scoped permissions and expiration dates
- Complete Audit Trail: Audit logs track who pushed, pulled, deleted, or scanned artifacts
When to Choose Harbor Over Alternatives
Organizations run Harbor when they need a private container registry with security controls that hosted registries charge for or simply do not offer, with air-gapped environments, regulated industries, and multi-cloud setups being typical use cases.
Compared to Docker Hub, Harbor offers built-in vulnerability scanning, image signing, RBAC, audit logging, and multi-registry replication — features that require Docker Hub paid plans or are unavailable. For organizations with data residency requirements, compliance mandates, or the need for unlimited private repositories, Harbor provides a compelling self-hosted alternative.
Understanding Harbor’s Multi-tenancy Architecture
Before diving into installation, it’s essential to understand how Harbor implements multi-tenancy and how this architecture supports organizational isolation and security.
Projects as Tenant Boundaries
Artifacts within Harbor are owned by a project, and this grouping allows settings and permissions to be tuned for sets of artifacts as opposed to a purely global level. Projects serve as the fundamental unit of multi-tenancy in Harbor, acting as isolated namespaces that separate container images, Helm charts, and other OCI artifacts by team, department, or customer.
Harbor’s multi-tenancy capabilities include projects acting as namespaces that isolate models by team, environment, or use case, along with fine-grained RBAC for controlling who can push, pull, or administer artifacts. This project-based isolation ensures that different tenants cannot access each other’s artifacts without explicit permission grants.
Role-Based Access Control (RBAC)
Users access different repositories through ‘projects’ and a user can have different permission for images or Helm charts under a project. Harbor implements a sophisticated RBAC system with predefined roles that can be assigned at the project level:
- Guest: Read-only access to view and pull artifacts
- Developer: Read-write permissions to push and pull images
- Maintainer: Can manage project members and configure project settings
- Project Admin: Full control over the project including read-write-configure capabilities
This granular permission model allows organizations to implement the principle of least privilege, ensuring users and automated systems only have access to the resources they need.
Authentication Integration
In the simplest cases, users can be created by Harbor itself and managed internally, however, this doesn’t scale particularly well, so Harbor also provides integration into other popular services such as OIDC, Active Directory, and LDAP. This flexibility allows organizations to leverage existing identity management infrastructure, reducing administrative overhead and ensuring consistent access policies across systems.
Prerequisites and System Requirements
Before installing Harbor, ensure your environment meets the necessary requirements for a production-ready deployment.
Hardware Requirements
For a production Harbor deployment supporting multiple tenants, consider the following minimum specifications:
- CPU: 4 cores minimum (8+ cores recommended for high-traffic environments)
- Memory: 8 GB RAM minimum (16+ GB recommended)
- Storage: Depends on image volume; start with 100 GB and plan for growth
- Network: Stable network connectivity with sufficient bandwidth for image push/pull operations
Software Prerequisites
Harbor requires the following software components:
- Operating System: Linux distribution (Ubuntu 20.04+, CentOS 7+, RHEL 7+, or similar)
- Docker Engine: Version 20.10.0 or higher
- Docker Compose: Version 1.29.0 or higher (for Docker Compose installation method)
- Kubernetes: Version 1.20+ (if deploying via Helm)
- OpenSSL: For generating SSL/TLS certificates
Network and Domain Configuration
For a production deployment, you’ll need:
- A fully qualified domain name (FQDN) pointing to your Harbor server
- SSL/TLS certificates (self-signed for testing, CA-signed for production)
- Open firewall ports: 80 (HTTP), 443 (HTTPS), and optionally 4443 (Notary)
Installing Harbor: Step-by-Step Guide
Harbor can be installed on any Kubernetes environment or on a system with Docker support. This guide covers both installation methods, starting with the Docker Compose approach for simplicity, followed by Kubernetes deployment using Helm charts.
Method 1: Installing Harbor with Docker Compose
Docker Compose provides the quickest path to getting Harbor up and running, making it ideal for development environments and smaller deployments.
Step 1: Install Docker and Docker Compose
First, ensure Docker and Docker Compose are installed on your system. On Ubuntu, you can install them with the following commands:
# Update package index
sudo apt update
# Install prerequisites
sudo apt install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine and Docker Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
# Verify installation
docker --version
docker compose version
Step 2: Download Harbor
Download binaries of Harbor release and follow Installation & Configuration Guide to install Harbor. You can download the latest Harbor release from the official GitHub repository:
# Download the latest Harbor release
cd /opt
curl -s https://api.github.com/repos/goharbor/harbor/releases/latest | grep browser_download_url | cut -d '"' -f 4 | grep '.tgz$' | wget -i -
# Extract the archive
tar xzvf harbor-offline-installer-*.tgz
# Navigate to Harbor directory
cd harbor
Step 3: Configure Harbor
Harbor uses a YAML configuration file that must be customized for your environment:
# Copy the template configuration file
cp harbor.yml.tmpl harbor.yml
# Edit the configuration file
nano harbor.yml
Key configuration parameters to modify:
# The hostname or IP address of your Harbor server
hostname: harbor.yourdomain.com
# HTTP configuration
http:
port: 80
# HTTPS configuration (recommended for production)
https:
port: 443
certificate: /path/to/your/certificate.crt
private_key: /path/to/your/private_key.key
# Harbor admin password (change this!)
harbor_admin_password: YourSecurePassword123!
# Database configuration
database:
password: DatabasePassword123!
max_idle_conns: 100
max_open_conns: 900
# Data storage location
data_volume: /data
# Log configuration
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
Step 4: Generate SSL Certificates (Optional but Recommended)
For production deployments, use CA-signed certificates. For testing, you can generate self-signed certificates:
# Create certificate directory
mkdir -p /opt/harbor/certs
cd /opt/harbor/certs
# Generate private key
openssl genrsa -out harbor.key 4096
# Generate certificate signing request
openssl req -new -key harbor.key -out harbor.csr -subj "/C=US/ST=State/L=City/O=Organization/CN=harbor.yourdomain.com"
# Generate self-signed certificate (valid for 365 days)
openssl x509 -req -days 365 -in harbor.csr -signkey harbor.key -out harbor.crt
# Update harbor.yml with certificate paths
# certificate: /opt/harbor/certs/harbor.crt
# private_key: /opt/harbor/certs/harbor.key
Step 5: Install Harbor with Trivy Scanner
Trivy is the default scanner since Harbor v2.2. To install Harbor with the Trivy vulnerability scanner enabled:
# Run the installation script with Trivy
sudo ./install.sh --with-trivy
# Verify all containers are running
docker compose ps
You should see output showing all Harbor services running, including harbor-core, harbor-portal, harbor-db, registry, trivy-adapter, and others.
Step 6: Access Harbor Web Interface
Once the installation is complete, you should be able to access the Harbor UI in your web browser at https://harbor.yourdomain.com and log in with the admin user and the password you set.
Method 2: Installing Harbor on Kubernetes with Helm
If you want to deploy Harbor on Kubernetes, please use the Harbor chart. Kubernetes deployment offers better scalability, high availability, and integration with cloud-native ecosystems.
Step 1: Add Harbor Helm Repository
# Add Harbor Helm repository
helm repo add harbor https://helm.goharbor.io
# Update Helm repositories
helm repo update
# Create namespace for Harbor
kubectl create namespace harbor
Step 2: Create Helm Values File
Create a custom values file to configure your Harbor deployment:
cat > harbor-values.yaml <<EOF
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: harbor.yourdomain.com
className: nginx
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
externalURL: https://harbor.yourdomain.com
persistence:
enabled: true
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
storageClass: "fast-ssd"
size: 500Gi
database:
storageClass: "fast-ssd"
size: 10Gi
redis:
storageClass: "fast-ssd"
size: 1Gi
harborAdminPassword: "ChangeThisPassword123!"
database:
type: internal
redis:
type: internal
trivy:
enabled: true
notary:
enabled: true
EOF
Step 3: Install Harbor via Helm
# Install Harbor
helm install harbor harbor/harbor
-n harbor
-f harbor-values.yaml
# Wait for all components to be ready
kubectl wait --for=condition=available --timeout=600s
deployment --all -n harbor
# Check pod status
kubectl get pods -n harbor
# Get Harbor admin password
kubectl get secret harbor-core -n harbor -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 -d
Configuring Multi-tenancy in Harbor
With Harbor installed, the next step is configuring multi-tenancy to support multiple teams, departments, or customers within your organization.
Creating Projects for Tenants
You can create multiple projects in Harbor to separate the artifacts stored by different teams or sub-organizations within an enterprise. Projects can be created through the Harbor web interface or programmatically via the API.
Creating Projects via Web Interface
To create a project through the Harbor portal:
- Log in to Harbor as an administrator
- Click on “Projects” in the left navigation menu
- Click the “NEW PROJECT” button
- Configure the project settings:
- Project Name: Use a descriptive name (e.g., “team-frontend”, “customer-acme”)
- Access Level: Choose “Public” (anyone can pull) or “Private” (requires authentication)
- Storage Quota: Set a limit to prevent any single tenant from consuming excessive storage
- Proxy Cache: Optionally configure the project as a proxy cache for external registries
- Click “OK” to create the project
Creating Projects via API
For automated project creation or bulk operations, use the Harbor REST API:
# Set Harbor credentials
HARBOR_URL="https://harbor.yourdomain.com"
HARBOR_USER="admin"
HARBOR_PASSWORD="YourSecurePassword123!"
# Create multiple projects
for project in team-frontend team-backend team-ml customer-alpha customer-beta; do
curl -X POST "${HARBOR_URL}/api/v2.0/projects"
-H "Content-Type: application/json"
-u "${HARBOR_USER}:${HARBOR_PASSWORD}"
-d "{
"project_name": "${project}",
"public": false,
"storage_limit": 107374182400
}"
echo "Created project: $project"
done
# List all projects
curl -X GET "${HARBOR_URL}/api/v2.0/projects"
-u "${HARBOR_USER}:${HARBOR_PASSWORD}" | jq .
Configuring Project-Level Settings
Each project in Harbor can be configured independently with settings that enforce security policies and resource limits.
Storage Quotas
Storage quotas prevent individual tenants from consuming excessive disk space:
- Navigate to the project
- Click on “Configuration” tab
- Under “Resource Management”, set the storage quota (e.g., 100 GB)
- Click “Save”
Vulnerability Scanning Policies
Configure automatic vulnerability scanning for images pushed to the project:
- Go to project “Configuration”
- Enable “Automatically scan images on push”
- Set “Prevent vulnerable images from running” to block images with critical vulnerabilities
- Configure severity threshold (e.g., block images with “High” or “Critical” vulnerabilities)
Tag Retention Policies
Retention policies automatically clean up old or unused images to manage storage efficiently:
- Navigate to project “Policy” tab
- Click “Add Rule” under Tag Retention
- Configure retention criteria:
- Repository matching pattern (e.g., “**” for all repositories)
- Retention rule (e.g., “retain the most recently pushed 10 artifacts”)
- Tag matching pattern (e.g., exclude “latest” and “production” tags)
- Click “Add” and then “Run Now” to test the policy
Content Trust and Image Signing
Enable content trust to ensure only signed images can be pulled:
- In project “Configuration”, enable “Enable content trust”
- This requires images to be signed using Docker Content Trust or Cosign
- Unsigned images will be rejected when users attempt to pull them
Managing User Access and Permissions
Effective multi-tenancy requires careful management of user access and permissions to ensure tenants can only access their designated resources.
User Management Strategies
Harbor supports multiple authentication backends, allowing you to choose the approach that best fits your organization’s identity management infrastructure.
Local User Management
For small deployments or testing, you can create users directly in Harbor:
- Log in as admin
- Navigate to “Administration” → “Users”
- Click “NEW USER”
- Fill in user details (username, email, full name, password)
- Click “OK”
LDAP/Active Directory Integration
For enterprise deployments, integrate Harbor with your existing LDAP or Active Directory:
- Navigate to “Administration” → “Configuration” → “Authentication”
- Select “LDAP” as the authentication mode
- Configure LDAP settings:
- LDAP URL: ldap://ldap.yourdomain.com:389
- LDAP Search DN: cn=admin,dc=yourdomain,dc=com
- LDAP Base DN: dc=yourdomain,dc=com
- LDAP Filter: (objectClass=person)
- LDAP UID: uid
- LDAP Scope: Subtree
- Test the connection
- Click “Save”
OIDC Integration
For modern identity providers like Okta, Auth0, or Keycloak:
- In “Authentication” settings, select “OIDC”
- Configure OIDC parameters:
- OIDC Provider Name: Your provider name
- OIDC Endpoint: https://your-idp.com
- OIDC Client ID: Your client ID
- OIDC Client Secret: Your client secret
- OIDC Scope: openid,profile,email
- Verify and save
Assigning Users to Projects
Once users are authenticated, assign them to projects with appropriate roles:
- Navigate to the project
- Click on “Members” tab
- Click “USER” or “GROUP” to add members
- Search for the user or group
- Select the appropriate role:
- Guest: Read-only access to pull images
- Developer: Can push and pull images
- Maintainer: Can manage project members and configure settings
- Project Admin: Full control over the project
- Click “OK”
Robot Accounts for CI/CD Integration
Robot accounts are service accounts in Harbor with specific permissions, used for automated operations like CI/CD pipelines pushing or pulling images without requiring human credentials.
To create a robot account:
- Navigate to the project
- Click “Robot Accounts” tab
- Click “NEW ROBOT ACCOUNT”
- Configure the robot account:
- Name: Descriptive name (e.g., “ci-pipeline-bot”)
- Expiration time: Set an expiration date for security
- Permissions: Select specific repositories and actions (push, pull, delete)
- Click “ADD”
- Copy the generated token immediately (it won’t be shown again)
Use the robot account in your CI/CD pipeline:
# In your CI/CD pipeline (e.g., GitLab CI, Jenkins)
docker login harbor.yourdomain.com -u 'robot$ci-pipeline-bot' -p 'TOKEN_HERE'
docker build -t harbor.yourdomain.com/team-frontend/app:${CI_COMMIT_SHA} .
docker push harbor.yourdomain.com/team-frontend/app:${CI_COMMIT_SHA}
Security Features for Multi-tenant Environments
Security is paramount in multi-tenant environments where multiple teams or customers share infrastructure. Harbor provides comprehensive security features to protect your container supply chain.
Vulnerability Scanning
By utilizing popular image scanners, such as Trivy, images can be automatically scanned for known vulnerabilities, and the results of these scans can be leveraged to prevent pulling of artifacts with unaddressed security issues.
Configuring Automatic Scanning
Enable automatic scanning at the system or project level:
- For system-wide scanning: “Administration” → “Interrogation Services” → Configure Trivy settings
- For project-level scanning: Project → “Configuration” → Enable “Automatically scan images on push”
- Set up scheduled scans to re-scan existing images for newly discovered vulnerabilities
Vulnerability Prevention Policies
Configure policies to prevent vulnerable images from being deployed:
- In project “Configuration”, enable “Prevent vulnerable images from running”
- Set the severity threshold (e.g., “High” or “Critical”)
- Images with vulnerabilities at or above this threshold cannot be pulled
Viewing Scan Results
To view vulnerability scan results:
- Navigate to the project and repository
- Click on an artifact/tag
- View the “Vulnerabilities” tab for detailed scan results
- Review CVE details, severity levels, and available fixes
Image Signing and Content Trust
Harbor supports signing container images using Docker Content Trust (leveraging Notary) for guaranteeing authenticity and provenance, and policies that prevent unsigned images from being deployed can also be activated.
Enabling Content Trust
To enable content trust for a project:
- Navigate to project “Configuration”
- Enable “Enable content trust”
- Enable “Prevent unsigned images from being pulled”
Signing Images with Docker Content Trust
# Enable Docker Content Trust
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://harbor.yourdomain.com:4443
# Push and sign an image
docker push harbor.yourdomain.com/team-frontend/app:v1.0
# The first push will prompt you to create signing keys
# Follow the prompts to set passphrases for root and repository keys
Signing with Cosign
For modern signing workflows, use Cosign:
# Install Cosign
curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64"
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
sudo chmod +x /usr/local/bin/cosign
# Generate key pair
cosign generate-key-pair
# Sign an image
cosign sign --key cosign.key harbor.yourdomain.com/team-frontend/app:v1.0
# Verify signature
cosign verify --key cosign.pub harbor.yourdomain.com/team-frontend/app:v1.0
Audit Logging and Compliance
All the operations to the repositories are tracked through logs. Harbor maintains comprehensive audit logs that track all user activities, making it easier to meet compliance requirements and investigate security incidents.
Viewing Audit Logs
- Navigate to “Administration” → “Logs”
- Filter logs by:
- Username
- Operation type (push, pull, delete, create, etc.)
- Resource type (project, repository, artifact)
- Time range
- Export logs for external analysis or archival
Integrating with SIEM Systems
For enterprise compliance, integrate Harbor logs with your SIEM system:
# Configure Harbor to send logs to syslog
# Edit harbor.yml
log:
level: info
external_endpoint:
protocol: tcp
host: syslog.yourdomain.com
port: 514
# Restart Harbor to apply changes
docker compose down
docker compose up -d
Network Security and Access Control
Configuring HTTPS
Always use HTTPS in production to encrypt data in transit:
- Obtain SSL/TLS certificates from a trusted CA (Let’s Encrypt, DigiCert, etc.)
- Configure harbor.yml with certificate paths
- Restart Harbor
Firewall Configuration
Restrict access to Harbor using firewall rules:
# Allow HTTPS traffic
sudo ufw allow 443/tcp
# Allow HTTP (if needed for redirect)
sudo ufw allow 80/tcp
# Allow Notary (if using Docker Content Trust)
sudo ufw allow 4443/tcp
# Restrict access to specific IP ranges (optional)
sudo ufw allow from 10.0.0.0/8 to any port 443 proto tcp
# Enable firewall
sudo ufw enable
Image Replication for Multi-site Deployments
Images and charts can be replicated (synchronized) between multiple registry instances based on policies with using filters (repository, tag and label), and Harbor automatically retries a replication if it encounters any errors, which can be used to assist loadbalancing, achieve high availability, and facilitate multi-datacenter deployments in hybrid and multi-cloud scenarios.
Setting Up Replication Endpoints
Replication targets include other Harbor instances, Docker Hub, AWS ECR, Google GCR/GAR, Azure ACR, and any OCI-compliant registry.
To configure a replication endpoint:
- Navigate to “Administration” → “Registries”
- Click “NEW ENDPOINT”
- Configure endpoint details:
- Provider: Select the registry type (Harbor, Docker Hub, AWS ECR, etc.)
- Name: Descriptive name for the endpoint
- Endpoint URL: Registry URL
- Access ID/Secret: Authentication credentials
- Test the connection
- Click “OK”
Creating Replication Rules
Define replication policies to automatically sync images:
- Navigate to “Administration” → “Replications”
- Click “NEW REPLICATION RULE”
- Configure the rule:
- Name: Descriptive rule name
- Replication mode: Push (to remote) or Pull (from remote)
- Source registry: Select source
- Destination registry: Select target endpoint
- Trigger mode: Manual, Scheduled, or Event-based
- Filters: Specify which repositories, tags, or labels to replicate
- Click “SAVE”
Use Cases for Replication
- Disaster Recovery: Replicate critical images to a secondary Harbor instance in a different region
- Geographic Distribution: Sync images to regional registries for faster pull times
- Hybrid Cloud: Replicate between on-premises Harbor and cloud registries
- Development/Production Separation: Promote images from dev to production registries
Working with Harbor: Practical Workflows
Once Harbor is configured for multi-tenancy, teams can begin using it for their container workflows.
Pushing Images to Harbor
To push an image to Harbor:
# Log in to Harbor
docker login harbor.yourdomain.com
# Tag your image with Harbor registry path
docker tag myapp:latest harbor.yourdomain.com/team-frontend/myapp:v1.0
# Push the image
docker push harbor.yourdomain.com/team-frontend/myapp:v1.0
Pulling Images from Harbor
# Log in to Harbor (if pulling private images)
docker login harbor.yourdomain.com
# Pull the image
docker pull harbor.yourdomain.com/team-frontend/myapp:v1.0
# Run the container
docker run -d harbor.yourdomain.com/team-frontend/myapp:v1.0
Using Harbor with Kubernetes
To pull images from Harbor in Kubernetes, create an image pull secret:
# Create a Docker registry secret
kubectl create secret docker-registry harbor-registry
--docker-server=harbor.yourdomain.com
--docker-username=your-username
--docker-password=your-password
[email protected]
-n your-namespace
# Reference the secret in your pod spec
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: harbor.yourdomain.com/team-frontend/myapp:v1.0
imagePullSecrets:
- name: harbor-registry
Proxy Cache for External Registries
Harbor’s proxy cache feature allows Harbor to act as a caching proxy for external registries, reducing bandwidth usage and improving pull performance.
To configure a proxy cache project:
- Create a new project
- Select “Proxy Cache” as the project type
- Choose the target registry (Docker Hub, Quay.io, etc.)
- Configure credentials if needed
- Pull images through Harbor using the proxy cache path
# Instead of pulling from Docker Hub directly
docker pull nginx:latest
# Pull through Harbor proxy cache
docker pull harbor.yourdomain.com/dockerhub-proxy/library/nginx:latest
Backup and Disaster Recovery
Protecting your Harbor deployment and its data is critical for business continuity.
Backing Up Harbor Data
Harbor uses a database to store its data, and by default, it uses a PostgreSQL database that is managed by Docker.
To back up Harbor:
# Stop Harbor
cd /opt/harbor
docker compose down
# Backup the data directory
sudo tar -czf harbor-backup-$(date +%Y%m%d).tar.gz /data
# Backup the configuration
sudo cp harbor.yml harbor.yml.backup
# Backup the database (if using external database)
docker exec harbor-db pg_dump -U postgres registry > harbor-db-backup-$(date +%Y%m%d).sql
# Restart Harbor
docker compose up -d
Automated Backup Script
#!/bin/bash
# harbor-backup.sh
BACKUP_DIR="/backup/harbor"
DATE=$(date +%Y%m%d-%H%M%S)
HARBOR_DIR="/opt/harbor"
DATA_DIR="/data"
# Create backup directory
mkdir -p $BACKUP_DIR
# Stop Harbor
cd $HARBOR_DIR
docker compose down
# Backup data volume
tar -czf $BACKUP_DIR/harbor-data-$DATE.tar.gz $DATA_DIR
# Backup configuration
cp $HARBOR_DIR/harbor.yml $BACKUP_DIR/harbor-config-$DATE.yml
# Restart Harbor
docker compose up -d
# Remove backups older than 30 days
find $BACKUP_DIR -name "harbor-*" -mtime +30 -delete
echo "Backup completed: $BACKUP_DIR/harbor-data-$DATE.tar.gz"
Schedule this script with cron:
# Run backup daily at 2 AM
0 2 * * * /usr/local/bin/harbor-backup.sh >> /var/log/harbor-backup.log 2>&1
Restoring from Backup
# Stop Harbor
cd /opt/harbor
docker compose down
# Restore data directory
sudo rm -rf /data
sudo tar -xzf /backup/harbor/harbor-data-20260402.tar.gz -C /
# Restore configuration
sudo cp /backup/harbor/harbor-config-20260402.yml /opt/harbor/harbor.yml
# Restart Harbor
docker compose up -d
Monitoring and Performance Optimization
Monitoring Harbor’s health and performance ensures optimal operation and helps identify issues before they impact users.
Monitoring Harbor Health
Harbor exposes health check endpoints:
# Check Harbor health
curl -k https://harbor.yourdomain.com/api/v2.0/health
# Expected response
{
"status": "healthy",
"components": [
{"name": "core", "status": "healthy"},
{"name": "database", "status": "healthy"},
{"name": "redis", "status": "healthy"},
{"name": "registry", "status": "healthy"}
]
}
Prometheus Metrics
Harbor exposes Prometheus metrics for monitoring:
# Enable metrics in harbor.yml
metric:
enabled: true
port: 9090
path: /metrics
# Scrape metrics with Prometheus
curl http://harbor.yourdomain.com:9090/metrics
Performance Optimization Tips
- Use SSD storage: Store Harbor data on fast SSD drives for better I/O performance
- Configure Redis caching: Ensure Redis has sufficient memory allocated
- Database tuning: Optimize PostgreSQL settings for your workload
- Enable garbage collection: Schedule regular garbage collection to reclaim storage
- Use proxy cache: Reduce external registry pulls by caching frequently used images
- Implement replication: Distribute load across multiple Harbor instances
Garbage Collection
Garbage collection is the process of reclaiming storage space by removing unreferenced blobs and artifacts that are no longer needed.
To run garbage collection:
- Navigate to “Administration” → “Garbage Collection”
- Click “GC NOW” for immediate collection
- Or schedule regular garbage collection (e.g., weekly at 2 AM)
Troubleshooting Common Issues
Cannot Push Images
Symptoms: “denied: requested access to the resource is denied” error
Solutions:
- Verify user has Developer or higher role in the project
- Check project storage quota hasn’t been exceeded
- Ensure user is authenticated:
docker login harbor.yourdomain.com - Verify project name in image tag matches existing project
SSL Certificate Errors
Symptoms: “x509: certificate signed by unknown authority” error
Solutions:
- Add Harbor’s CA certificate to Docker’s trusted certificates
- For self-signed certificates, copy the CA cert to
/etc/docker/certs.d/harbor.yourdomain.com/ca.crt - Restart Docker daemon:
sudo systemctl restart docker
Slow Image Push/Pull
Symptoms: Image operations take excessive time
Solutions:
- Check network bandwidth and latency
- Verify storage I/O performance
- Increase Docker daemon’s max concurrent uploads/downloads
- Consider using Harbor replication for geographically distributed teams
- Enable proxy cache for frequently pulled external images
Database Connection Issues
Symptoms: Harbor UI shows errors or won’t load
Solutions:
- Check database container status:
docker compose ps - Verify database credentials in harbor.yml
- Check database logs:
docker compose logs harbor-db - Ensure database has sufficient resources (CPU, memory, disk)
Advanced Multi-tenancy Scenarios
Customer-Facing Container Distribution
Harbor can be used to distribute containerized software to external customers:
- Create separate projects for each customer
- Use robot accounts with expiration dates for customer access
- Implement webhook notifications when new versions are available
- Set up replication to customer-specific registries if needed
- Use project quotas to manage storage per customer
Multi-Region Deployment
For global organizations, deploy Harbor in multiple regions:
- Deploy Harbor instances in each major region (US, EU, APAC)
- Configure bidirectional replication between instances
- Use DNS-based load balancing to route users to nearest instance
- Implement consistent LDAP/OIDC authentication across all instances
- Centralize monitoring and logging for all instances
Compliance and Regulatory Requirements
For regulated industries (healthcare, finance, government):
- Enable comprehensive audit logging
- Implement mandatory vulnerability scanning with blocking policies
- Require image signing for all production images
- Configure retention policies to meet data retention requirements
- Use LDAP/AD integration for centralized access control
- Implement network segmentation and firewall rules
- Regular backup and disaster recovery testing
- Document all security controls and procedures
Best Practices for Multi-tenant Harbor Deployments
Security Best Practices
- Always use HTTPS: Never run Harbor over plain HTTP in production
- Change default passwords: Immediately change the admin password after installation
- Enable vulnerability scanning: Configure automatic scanning on push
- Implement image signing: Require signed images for production deployments
- Use robot accounts: Never use personal credentials in CI/CD pipelines
- Regular security updates: Keep Harbor and its components up to date
- Principle of least privilege: Grant users minimum necessary permissions
- Enable audit logging: Monitor and review logs regularly
Operational Best Practices
- Implement backup strategy: Regular automated backups with tested restore procedures
- Monitor resource usage: Track storage, CPU, memory, and network metrics
- Set storage quotas: Prevent individual projects from consuming excessive storage
- Configure retention policies: Automatically clean up old or unused images
- Schedule garbage collection: Regular cleanup to reclaim storage space
- Document procedures: Maintain documentation for common operations and troubleshooting
- Test disaster recovery: Regularly test backup restoration and failover procedures
- Capacity planning: Monitor growth trends and plan for scaling
Organizational Best Practices
- Naming conventions: Establish consistent naming for projects, repositories, and tags
- Project structure: Organize projects by team, application, or environment
- Access control policies: Define clear policies for who can access what
- Tagging strategy: Use semantic versioning and meaningful tags
- Training and documentation: Ensure teams understand how to use Harbor effectively
- Change management: Implement approval processes for configuration changes
- Communication: Establish channels for announcing maintenance and updates
Integrating Harbor with Your DevOps Ecosystem
CI/CD Pipeline Integration
Example GitLab CI pipeline:
stages:
- build
- scan
- deploy
variables:
HARBOR_REGISTRY: harbor.yourdomain.com
HARBOR_PROJECT: team-frontend
IMAGE_NAME: myapp
build:
stage: build
script:
- docker login -u robot$ci-bot -p $HARBOR_TOKEN $HARBOR_REGISTRY
- docker build -t $HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHA .
- docker push $HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHA
scan:
stage: scan
script:
- |
# Wait for Harbor to scan the image
sleep 30
# Check scan results via Harbor API
SCAN_STATUS=$(curl -u robot$ci-bot:$HARBOR_TOKEN
"$HARBOR_REGISTRY/api/v2.0/projects/$HARBOR_PROJECT/repositories/$IMAGE_NAME/artifacts/$CI_COMMIT_SHA"
| jq -r '.scan_overview.scan_status')
if [ "$SCAN_STATUS" != "Success" ]; then
echo "Vulnerability scan failed"
exit 1
fi
deploy:
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$HARBOR_REGISTRY/$HARBOR_PROJECT/$IMAGE_NAME:$CI_COMMIT_SHA
only:
- main
Webhook Integration
Configure webhooks to trigger actions when images are pushed:
- Navigate to project “Webhooks”
- Click “NEW WEBHOOK”
- Configure webhook:
- Endpoint URL: Your webhook receiver URL
- Events: Select events to trigger (push, pull, delete, scan completed)
- Authentication: Configure authentication if needed
- Test the webhook
- Click “CONTINUE”
Helm Chart Repository
Harbor can also serve as a Helm chart repository:
# Add Harbor as Helm repository
helm repo add myteam https://harbor.yourdomain.com/chartrepo/team-frontend
--username your-username
--password your-password
# Push a Helm chart to Harbor
helm package ./mychart
helm push mychart-1.0.0.tgz myteam
# Install from Harbor
helm install myapp myteam/mychart
Future-Proofing Your Harbor Deployment
Staying Current with Updates
Starting with v2.15.0, Harbor release artifacts are cryptographically signed using Cosign to ensure authenticity and integrity. Always verify Harbor releases before upgrading:
# Download Harbor release and signature
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-offline-installer-v2.15.0.tgz
wget https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-offline-installer-v2.15.0.tgz.sigstore.json
# Verify signature
cosign verify-blob
--bundle harbor-offline-installer-v2.15.0.tgz.sigstore.json
--certificate-oidc-issuer https://token.actions.githubusercontent.com
--certificate-identity-regexp '^https://github.com/goharbor/harbor/.github/workflows/publish_release.yml@refs/tags/v.*$'
harbor-offline-installer-v2.15.0.tgz
Scaling Considerations
As your organization grows, consider:
- Horizontal scaling: Deploy multiple Harbor instances with load balancing
- External database: Use managed PostgreSQL for better scalability and reliability
- External Redis: Use managed Redis or Redis cluster for caching
- Object storage: Use S3, Azure Blob, or GCS for image storage instead of local disk
- CDN integration: Use CDN for global image distribution
Emerging Use Cases
Harbor has always been OCI-compliant, meaning it can store and distribute any artifact that conforms to the OCI Distribution Specification, and the OCI specification’s extensibility means that AI models can now leverage that same infrastructure with the same security, governance, and operational maturity. Harbor is increasingly being used for:
- AI/ML model registry: Storing and distributing machine learning models as OCI artifacts
- WASM modules: Distributing WebAssembly modules
- Software Bill of Materials (SBOM): Storing and managing SBOMs alongside images
- Policy bundles: Distributing OPA policies and other configuration artifacts
Conclusion
Building a multi-tenant Docker registry with Harbor provides organizations with a powerful, secure, and scalable solution for managing container images across teams, departments, and even customers. Harbor bridges the gap as an open-source, enterprise-grade container registry that brings security, performance, and sovereignty to container image management, seamlessly integrating with existing operational paradigms and providing a robust solution for modern container image management needs.
By implementing the practices outlined in this guide—from proper installation and configuration to security hardening, multi-tenancy setup, and operational best practices—you can build a production-ready Harbor deployment that serves your organization’s needs today while remaining flexible enough to adapt to future requirements.
Key takeaways for successful Harbor multi-tenancy:
- Projects are the foundation: Use projects to create isolated namespaces for different tenants
- Security is paramount: Enable vulnerability scanning, image signing, and comprehensive audit logging
- Automation is essential: Use robot accounts, webhooks, and API integration for CI/CD workflows
- Plan for scale: Implement replication, monitoring, and capacity planning from the start
- Stay engaged: Join the Harbor community, stay current with updates, and contribute back
Whether you’re managing containers for a small development team or operating a large-scale multi-tenant platform serving hundreds of customers, Harbor provides the features, flexibility, and community support needed to succeed. Start with the basics, implement security best practices, and gradually adopt advanced features as your needs evolve.
For more information and resources, visit the official Harbor website, explore the GitHub repository, join the community on Slack, and consult the comprehensive Harbor documentation. The Harbor community is active, welcoming, and ready to help you succeed with your container registry deployment.