Cloud Native 11 min read

Step‑by‑Step Guide to Deploy Harbor 2.14.1 Private Registry with HTTPS and Trivy

This tutorial walks you through installing a private, secure Harbor 2.14.1 container registry on Linux, covering system prerequisites, Docker setup, offline installer download, detailed harbor.yml configuration, firewall adjustments, optional self‑signed certificates, installation scripts, verification, image push testing, common admin commands, production best practices, and troubleshooting tips.

Xiao Liu Lab
Xiao Liu Lab
Xiao Liu Lab
Step‑by‑Step Guide to Deploy Harbor 2.14.1 Private Registry with HTTPS and Trivy

Why Use a Private Registry

Container images are the primary delivery medium in cloud‑native environments. Public registries (e.g., Docker Hub) suffer from network instability, rate limits, and limited security controls. Harbor, a CNCF‑graduated open‑source registry, provides HTTPS, LDAP integration, image replication, content trust, and built‑in Trivy vulnerability scanning, making it suitable for enterprise use.

1. Environment Preparation

System Requirements

OS: Linux (Ubuntu 22.04 or Rocky Linux 9 recommended)
CPU: >= 2 cores
Memory: >= 4 GB (8 GB recommended)
Disk: >= 40 GB for image storage
Docker: >= 20.10
Docker Compose: >= 2.10 (v2+)

Install Docker and Docker Compose

Install Docker and Docker Compose if they are not already present. Use the official installers or offline packages as needed.

2. Download and Extract Harbor

cd /opt
wget https://github.com/goharbor/harbor/releases/download/v2.14.1/harbor-offline-installer-v2.14.1.tgz
# Alternative mirror if GitHub is blocked
# https://download.xlsys.cn/docker/harbor/harbor-offline-installer-v2.14.1.tgz
tar xvf harbor-offline-installer-v2.14.1.tgz
cd harbor

Resulting directory layout:

harbor/
├── common.sh
├── harbor.yml.tmpl
├── install.sh
├── prepare
└── harbor.v2.14.1.tar.gz   # all images are packaged here

3. Configure harbor.yml

Copy the template and edit the configuration:

cp harbor.yml.tmpl harbor.yml
vim harbor.yml

Key items (replace values with your own):

# Hostname (must match the URL you will use)
hostname: lab.example.com

# HTTPS (recommended)
https:
  port: 443
  certificate: /data/cert/fullchain.pem
  private_key: /data/cert/privkey.pem

# Administrator password (minimum 8 characters, mixed case + digits)
harbor_admin_password: YourSecurePass123!

# Data storage path
data_volume: /data/harbor

# Database (default embedded; replace for production)
database:
  password: root123
  max_idle_conns: 100
  max_open_conns: 900

# Logging
log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor

# Trivy vulnerability scanning (enabled by default in v2.14)
trivy:
  ignore_unfixed: false
  skip_update: false
  insecure: false

Note: The hostname must exactly match the URL you will access; otherwise HTTPS will report a certificate error.

4. Open Firewall Ports

# Ubuntu (ufw)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

# CentOS / Rocky (firewalld)
sudo firewall-cmd --permanent --add-port={80,443}/tcp
sudo firewall-cmd --reload

5. (Optional) Generate Self‑Signed Certificates for Testing

mkdir -p /data/cert && cd /data/cert
# Private key
openssl genrsa -out privkey.pem 4096
# Certificate signing request (replace CN with your hostname)
openssl req -new -key privkey.pem -out cert.csr -subj "/CN=harbor.example.com"
# Self‑signed certificate valid for 10 years
openssl x509 -req -days 3650 -in cert.csr -signkey privkey.pem -out fullchain.pem

Update the certificate and private_key paths in harbor.yml accordingly.

6. Install Harbor

Generate the Docker Compose file from harbor.yml and start the services:

# Generate configuration
sudo ./prepare
# Install and start containers
sudo ./install.sh

Successful installation prints:

[Step 5]: starting Harbor ...
✔ ----Harbor has been installed and started successfully.----

7. Verify the Service

Check container status:

docker compose -f /opt/harbor/docker-compose.yml ps

All services should show Up.

Open the Web UI in a browser: https://harbor.example.com Log in with username admin and the password defined in harbor.yml.

8. Client Image Push Test

8.1 Trust the Certificate (if self‑signed)

# Create Docker trust directory on the client
sudo mkdir -p /etc/docker/certs.d/harbor.example.com
# Copy the CA certificate from the server
scp root@harbor-server:/data/cert/fullchain.pem /etc/docker/certs.d/harbor.example.com/ca.crt
# Restart Docker daemon
sudo systemctl restart docker

8.2 Login and Push an Image

# Login to Harbor
docker login harbor.example.com
# Pull a test image, tag it, and push
docker pull alpine:latest
docker tag alpine:latest harbor.example.com/library/alpine:latest
docker push harbor.example.com/library/alpine:latest

Ensure the target project (e.g., library) exists in the Harbor UI before pushing.

9. Common Administration Commands

# Change to Harbor directory
cd /opt/harbor
# Stop all services
sudo docker compose down
# Start services in detached mode
sudo docker compose up -d
# View logs for a component (example: core)
sudo tail -f /var/log/harbor/core.log
# Upgrade Harbor (preserve data)
#   1. Backup /data/harbor and /var/log/harbor
#   2. Download new version, adjust harbor.yml if needed
#   3. Run ./install.sh with desired flags (e.g., --with-notary --with-trivy)

10. Production Best Practices

Enable OIDC integration (Keycloak, Auth0, Azure AD, etc.) for centralized authentication.

Activate Notary for image signing and content trust.

Configure external PostgreSQL and Redis for high availability.

Enable garbage collection to clean unused image layers.

Forward audit logs to a log aggregation system such as ELK or Splunk.

Deploy Harbor on Kubernetes using the official Helm chart for large‑scale clusters.

11. Troubleshooting

Certificate signed by unknown authority : Add the CA certificate to the client’s Docker trust store (see 8.1).

Port 80/443 already in use : Stop the conflicting service (e.g., Nginx, Apache) or change the ports in harbor.yml.

Push fails: project not found : Create the target project in the Harbor Web UI before pushing.

Installation stalls at “Loading harbor images” : Verify sufficient disk space and network connectivity; manually load images with docker load -i harbor.v2.14.1.tar.gz.

Conclusion

Following these steps yields a fully functional, enterprise‑grade private container registry. Harbor eliminates reliance on public registries, strengthens DevOps pipelines, and provides a solid foundation for Kubernetes deployments and security‑compliant operations.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesHarborContainer Registry
Xiao Liu Lab
Written by

Xiao Liu Lab

An operations lab passionate about server tinkering 🔬 Sharing automation scripts, high-availability architecture, alert optimization, and incident reviews. Using technology to reduce overtime and experience to avoid major pitfalls. Follow me for easier, more reliable operations!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.