Key Features
- Vulnerability Scanning: Integrated Trivy scanner automatically scans images for CVEs and security vulnerabilities.
- Role-Based Access Control: Fine-grained user permissions with project-level access controls and LDAP/OIDC integration.
- Image Signing: Content trust with Notary integration ensures image integrity and authenticity.
- Replication: Replicate images between Harbor instances or external registries for disaster recovery and geo-distribution.
- Garbage Collection: Automated cleanup of unused image layers to reclaim storage space.
System Requirements
Hardware Requirements
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU | 4+ vCPU |
| RAM | 4 GB | 8+ GB |
| Storage | 40 GB SSD | 100+ GB SSD |
| Network | 1 Gbps | 1 Gbps |
Important: For production workloads with vulnerability scanning enabled, we recommend at least 8 GB RAM. The Trivy scanner can be memory-intensive during image analysis.
Software Prerequisites
- Ubuntu 22.04 LTS or Ubuntu 24.04 LTS (recommended)
- Docker Engine version 20.10.x or later
- Docker Compose v2.x (included with Docker Engine)
- Domain name required for HTTPS (e.g., registry.yourdomain.com)
- SSL certificate (Let's Encrypt or commercial)
Recommended Cloud VPS Plans
Premium KVM 4GB
Premium KVM 8GB
Premium KVM 16GB
Server Preparation
Initial Server Setup
Connect to your RamNode VPS via SSH and perform initial system updates:
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install required dependencies
sudo apt install -y curl wget gnupg2 ca-certificates \
lsb-release apt-transport-https software-properties-commonConfigure Firewall
Configure UFW firewall to allow necessary traffic:
# Enable UFW
sudo ufw enable
# Allow SSH
sudo ufw allow 22/tcp
# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Verify firewall status
sudo ufw statusInstall Docker
Install Docker Engine using the official repository:
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add 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
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
# Add your user to docker group
sudo usermod -aG docker $USER
# Apply group changes
newgrp docker
# Verify installation
docker --version
docker compose versionHarbor Installation
Download Harbor
Download the latest Harbor offline installer:
# Create installation directory
sudo mkdir -p /opt/harbor
cd /opt/harbor
# Download Harbor (check for latest version)
HARBOR_VERSION="v2.11.1"
wget https://github.com/goharbor/harbor/releases/download/\
${HARBOR_VERSION}/harbor-offline-installer-${HARBOR_VERSION}.tgz
# Extract the installer
tar xzvf harbor-offline-installer-${HARBOR_VERSION}.tgz
cd harborCheck the Harbor GitHub releases page for the latest stable version.
Generate SSL Certificates
For production use, SSL/TLS is mandatory. Use Let's Encrypt for free certificates:
# Install Certbot
sudo apt install -y certbot
# Generate certificate (replace with your domain)
sudo certbot certonly --standalone \
-d registry.yourdomain.com \
--agree-tos \
--email admin@yourdomain.com
# Create directory for Harbor certificates
sudo mkdir -p /opt/harbor/harbor/certs
# Copy certificates
sudo cp /etc/letsencrypt/live/registry.yourdomain.com/fullchain.pem \
/opt/harbor/harbor/certs/
sudo cp /etc/letsencrypt/live/registry.yourdomain.com/privkey.pem \
/opt/harbor/harbor/certs/Ensure your domain DNS A record points to your RamNode VPS IP address before generating certificates.
Configure Harbor
Create the Harbor configuration file from the template:
# Copy template configuration
cp harbor.yml.tmpl harbor.yml
# Edit configuration
nano harbor.ymlUpdate the following key settings in harbor.yml:
# The hostname of your Harbor server
hostname: registry.yourdomain.com
# HTTP configuration (redirect to HTTPS)
http:
port: 80
# HTTPS configuration
https:
port: 443
certificate: /opt/harbor/harbor/certs/fullchain.pem
private_key: /opt/harbor/harbor/certs/privkey.pem
# Initial admin password (CHANGE THIS!)
harbor_admin_password: YourSecurePassword123!
# Database configuration
database:
password: db_secure_password_here
max_idle_conns: 50
max_open_conns: 1000
# Data storage path
data_volume: /data/harbor
# Trivy vulnerability scanner
trivy:
ignore_unfixed: false
skip_update: false
insecure: false
# Job service configuration
jobservice:
max_job_workers: 10
# Log configuration
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harborCreate Data Directory
Create the directory for Harbor data storage:
# Create data directory
sudo mkdir -p /data/harbor
# Set permissions
sudo chown -R 10000:10000 /data/harborRun the Installer
Execute the Harbor installation script with Trivy scanner enabled:
# Run installer with Trivy scanner
sudo ./install.sh --with-trivy
# For additional features, use:
# sudo ./install.sh --with-trivy --with-notary --with-chartmuseumThe installation may take several minutes as it loads container images and starts all services.
Verify Installation
Check that all Harbor containers are running:
docker compose psExpected containers:
- harbor-core
- harbor-db
- harbor-jobservice
- harbor-log
- harbor-portal
- nginx
- redis
- registry
- registryctl
- trivy-adapter
Post-Installation Configuration
Access the Web Interface
Open your browser and navigate to your Harbor instance:
https://registry.yourdomain.com| Field | Value |
|---|---|
| Username | admin |
| Password | Your configured password from harbor.yml |
Important: Immediately change the admin password after first login through Administration → Users.
Create a Project
Projects in Harbor are logical groupings for container images:
- Click 'New Project' in the web interface
- Enter a project name (e.g., 'myapp')
- Choose access level: Public (anonymous pull) or Private
- Set storage quota if needed
- Enable vulnerability scanning for automatic scans on push
Create Robot Accounts
Robot accounts provide secure, non-human access for CI/CD pipelines:
- Navigate to your project
- Click 'Robot Accounts' tab
- Click 'New Robot Account'
- Set name, expiration, and permissions (push/pull)
- Save the generated token securely - it won't be shown again
Docker Client Configuration
Login to Harbor
On machines that will push/pull images, configure Docker to use your registry:
# Login to Harbor
docker login registry.yourdomain.com
# Enter username and password when prompted
# For CI/CD, use robot account credentialsPush and Pull Images
Tag and push images to your Harbor registry:
# Tag an existing image
docker tag myapp:latest registry.yourdomain.com/myproject/myapp:latest
# Push the image
docker push registry.yourdomain.com/myproject/myapp:latest
# Pull the image
docker pull registry.yourdomain.com/myproject/myapp:latestUsing with Docker Compose
Reference Harbor images in your docker-compose.yml:
version: '3.8'
services:
web:
image: registry.yourdomain.com/myproject/webapp:1.0
ports:
- '8080:80'
api:
image: registry.yourdomain.com/myproject/api:1.0
ports:
- '3000:3000'Operations and Maintenance
Service Management
# Navigate to Harbor directory
cd /opt/harbor/harbor
# Stop Harbor
docker compose down
# Start Harbor
docker compose up -d
# Restart Harbor
docker compose restart
# View logs
docker compose logs -f
# View specific service logs
docker compose logs -f harbor-coreBackup and Restore
Regularly back up your Harbor data:
# Create backup directory
sudo mkdir -p /backup/harbor
# Stop Harbor before backup
cd /opt/harbor/harbor
docker compose down
# Backup data directory
sudo tar -czvf /backup/harbor/harbor-data-$(date +%Y%m%d).tar.gz \
/data/harbor
# Backup configuration
sudo cp harbor.yml /backup/harbor/harbor.yml.$(date +%Y%m%d)
# Start Harbor
docker compose up -dGarbage Collection
Reclaim storage space by removing deleted image layers:
# Method 1: Via Web UI
# Go to Administration > Garbage Collection > GC Now
# Method 2: Via Docker Compose
cd /opt/harbor/harbor
docker compose down
docker compose up -d registry
docker exec registry registry garbage-collect \
/etc/registry/config.yml
docker compose down
docker compose up -dSchedule garbage collection during low-usage periods as it can temporarily impact registry performance.
SSL Certificate Renewal
Set up automatic certificate renewal for Let's Encrypt:
#!/bin/bash
cd /opt/harbor/harbor
docker compose down
certbot renew
cp /etc/letsencrypt/live/registry.yourdomain.com/fullchain.pem \
/opt/harbor/harbor/certs/
cp /etc/letsencrypt/live/registry.yourdomain.com/privkey.pem \
/opt/harbor/harbor/certs/
docker compose up -dSet up a cron job for automatic renewal:
# Create the script
sudo nano /opt/harbor/renew-certs.sh
# Make script executable
sudo chmod +x /opt/harbor/renew-certs.sh
# Add to crontab (runs monthly)
sudo crontab -e
# Add this line:
0 0 1 * * /opt/harbor/renew-certs.shTroubleshooting
Cannot Access Web Interface
# Check if all containers are running
docker compose ps
# Check nginx logs
docker compose logs nginx
# Verify firewall rules
sudo ufw status
# Check if ports are listening
sudo ss -tlnp | grep -E '80|443'Docker Login Failed
# For self-signed certificates, add CA to Docker
sudo mkdir -p /etc/docker/certs.d/registry.yourdomain.com
sudo cp ca.crt /etc/docker/certs.d/registry.yourdomain.com/
# Restart Docker
sudo systemctl restart dockerOut of Disk Space
# Check disk usage
df -h /data/harbor
# Run garbage collection (see section above)
# Clean up Docker system
docker system prune -afDatabase Connection Issues
# Check database container
docker compose logs harbor-db
# Restart database
docker compose restart harbor-db
# Check database connectivity
docker exec harbor-db pg_isreadySecurity Best Practices
Access Control
- Use strong, unique passwords for all accounts
- Enable two-factor authentication via OIDC provider
- Use robot accounts for CI/CD with minimal required permissions
- Regularly audit user access and remove inactive accounts
- Set project quotas to prevent resource exhaustion
Vulnerability Scanning
- Enable 'Automatically scan images on push' for projects
- Set vulnerability severity thresholds to block deployment
- Schedule regular scans of existing images
- Review CVE reports and update base images regularly
Next Steps
You now have a fully functional Harbor container registry. Consider these enhancements:
- Configure LDAP/OIDC authentication for enterprise SSO
- Set up replication to a secondary Harbor instance for disaster recovery
- Integrate with your CI/CD pipeline for automated image builds and scanning
- Configure webhook notifications for security alerts
- Enable Notary for container image signing
Additional Resources
Harbor Documentation: goharbor.io/docs
Contact RamNode support at support@ramnode.com
Visit ramnode.com for VPS plans and documentation
