Install Harbor Registry on CentOS / Debian / Ubuntu

Posted on 282 views

How do I install Harbor container registry on CentOS / Debian / Ubuntu Linux?. Harbor is an open-source cloud native registry that stores, signs, and scans container images for vulnerabilities. If you’re looking for enterprise Docker image registry, then Harbor is the right tool for you. It has some of the best features only available in commercial Registry products like Quay.

Harbor fills a gap for applications and organizations that cannot use a public or cloud-based registry. You’ll enjoy a consistent experience across all clouds platforms. This guide will walk you through the installation of Harbor on any system with Docker support.

Features of Harbor Registry

  • Multi-tenant support
  • Security and vulnerability analysis support
  • Extensible API and web UI
  • Content signing and validation
  • ​Image replication across multiple Harbor instances
  • ​Identity integration and role-based access control

What You’ll Need

You need an operating system with support for docker and following system requirements:


Resource Capacity Description
CPU minimal 2 CPU 4 CPU is preferred
Mem minimal 4GB 8GB is preferred
Disk minimal 40GB 160GB is preferred


Software Version
Docker engine version 17.06.0-ce+ or higher
Docker Compose version 1.18.0 or higher
Openssl latest is preferred

Network ports

Port Protocol
4443 HTTPS

Let’s now start the installation of Harbor on Linux system – CentOS, Ubuntu & Debian Linux distribution.

Storage Preparation (Optional)

I’ll be using a secondary disk as data store for all container images – /dev/sdb

$ lsblk 
sda                      8:0    0  100G  0 disk 
├─sda1                   8:1    0    1G  0 part /boot
└─sda2                   8:2    0   74G  0 part 
  ├─rhel-root          253:0    0   10G  0 lvm  /
  ├─rhel-swap          253:1    0   16G  0 lvm  [SWAP]
  ├─rhel-home          253:2    0    4G  0 lvm  /home
  ├─rhel-var           253:3    0   20G  0 lvm  /var
  ├─rhel-var_log       253:4    0   10G  0 lvm  /var/log
  ├─rhel-var_log_audit 253:5    0    2G  0 lvm  /var/log/audit
  ├─rhel-tmp           253:6    0    8G  0 lvm  /tmp
  └─rhel-var_tmp       253:7    0    4G  0 lvm  /var/tmp
sdb                      8:16   0  200G  0 disk 
sr0                     11:0    1 1024M  0 rom  

Let’s prepare and mount this disk.

sudo parted -s -a optimal -- /dev/sdb mklabel gpt
sudo parted -s -a optimal -- /dev/sdb  mkpart primary 0% 100%
sudo parted -s -- /dev/sdb  align-check optimal 1
sudo pvcreate /dev/sdb1
sudo vgcreate vg0 /dev/sdb1
sudo lvcreate -n harbor -l +100%FREE vg0
sudo mkfs.xfs /dev/vg0/harbor
sudo mkdir /data
echo "/dev/vg0/harbor /data xfs defaults 0 0" | sudo tee -a /etc/fstab

Mount and confirm:

$ sudo mount -a
$ df -hT /data/
Filesystem             Type  Size  Used Avail Use% Mounted on
/dev/mapper/vg0-harbor xfs   200G  1.5G  199G   1% /data

Step 1: Install Docker Engine

Follow our guides below on installation of Docker Engine.

Step 2: Install Docker Compose

Our next installation is for docker-compose command. This is not available on system repositories. Follow instructions shared in our previous guide below.

Step 3: Download and Install Harbor

Download harbor installer.

curl -s | grep browser_download_url | cut -d '"' -f 4 | grep '\.tgz$' | wget -i -

You can also pull the latest Harbor release from the downloads page.

Unpack downloaded Harbor file.

tar xvzf harbor-offline-installer*.tgz

Change into harbor created after file unpacking.

cd harbor

Harbor Installation without SSL

In the first setup, we’ll consider installation without TLS/SSL. Copy configuration template:

cp harbor.yml.tmpl harbor.yml

Edit harbor configuration file, and set like below.

$ nano harbor.yml
# The IP address or hostname to access admin UI and registry service.

harbor_admin_password: [email protected]$d

# Harbor DB configuration
  password: [email protected]$d

Harbor Installation with Let’s Encrypt SSL

if your server has a public IP, you can use Let’s Encrypt free SSL certificate.

Start by installing certbot tool.

# Ubuntu / Debian
sudo apt update && sudo apt install certbot -y
# Fedora
sudo dnf install certbot -y

# RHEL 8/9 based systems
sudo dnf -y install epel-release

# CentOS 7
sudo yum -y install epel-release
sudo yum -y install certbot

# Arch / Manjaro
sudo pacman -S certbot

Then obtain SSL certificate.

export DOMAIN=""
export EMAIL="[email protected]"
sudo certbot certonly --standalone -d $DOMAIN --preferred-challenges http --agree-tos  -m $EMAIL --keep-until-expiring

Configure https related config.

harbor_admin_password: [email protected]$d

# Harbor DB configuration
  password: [email protected]$d

  port: 80

  port: 443
  certificate: /etc/letsencrypt/live/
  private_key: /etc/letsencrypt/live/

Harbor Installation with Self Signed SSL Certificates

For Self signed certificates, create certificate configuration file – Modify the file to match your values.

$ cd /etc/pki/tls/certs
$ sudo vim harbor_certs.cnf
[ req ]  
default_bits       = 4096
default_md         = sha512
default_keyfile    = harbor_registry.key
prompt             = no
encrypt_key        = no
distinguished_name = req_distinguished_name

# distinguished_name
[ req_distinguished_name ]  
countryName            = "KE" 
localityName           = "Nairobi"
stateOrProvinceName    = "Nairobi"
organizationName       = "Computingpost"
commonName             = ""
emailAddress           = "[email protected]"

Generate key and csr:

sudo openssl req -out harbor_registry.csr -newkey rsa:4096 --sha512 -nodes -keyout harbor_registry.key -config harbor_certs.cnf

Create self-singed certificate with 10 years expiration date:

sudo openssl x509 -in harbor_registry.csr -out harbor_registry.crt -req -signkey harbor_registry.key -days 3650

To view certificate details use the command:

openssl x509 -text -noout -in harbor_registry.crt

Configure https related config.

harbor_admin_password: [email protected]$d

# Harbor DB configuration
  password: [email protected]$d

  port: 80

  port: 443
  certificate: ./harbor_registry.crt
  private_key: ./harbor_registry.key

Install Harbor Docker image registry

Once harbor.yml and storage backend (optional) are configured, install and start Harbor using the script.

sudo ./prepare
sudo ./

Note that the default installation does not include Notary or Clair service. These services are used for vulnerability scanning.

To see installer options, run:

$ ./ --help
Note: Please set hostname and other necessary attributes in harbor.yml first. DO NOT use localhost or for hostname, because Harbor needs to be accessed by external clients.
Please set --with-notary if needs enable Notary in Harbor, and set ui_url_protocol/ssl_cert/ssl_cert_key in harbor.yml bacause notary must run under https. 
Please set --with-chartmuseum if needs enable Chartmuseum in Harbor

Example, enable notary and Chartmuseum:

 sudo ./ --with-notary --with-chartmuseum

To include Notary service, you must enable and configure https in harbor.yml. Confirm that all containers are started.

[Step 5]: starting Harbor ...
[+] Running 10/10
 ⠿ Network harbor_harbor        Created                                                                                                                                                          0.1s
 ⠿ Container harbor-log         Started                                                                                                                                                          0.7s
 ⠿ Container registry           Started                                                                                                                                                          1.6s
 ⠿ Container redis              Started                                                                                                                                                          1.4s
 ⠿ Container registryctl        Started                                                                                                                                                          1.2s
 ⠿ Container harbor-portal      Started                                                                                                                                                          1.6s
 ⠿ Container harbor-db          Started                                                                                                                                                          1.3s
 ⠿ Container harbor-core        Started                                                                                                                                                          2.0s
 ⠿ Container nginx              Started                                                                                                                                                          2.5s
 ⠿ Container harbor-jobservice  Started                                                                                                                                                          2.5s
✔ ----Harbor has been installed and started successfully.----

Harbor log files are stored in the directory /var/log/harbor/:

$ ls -1 /var/log/harbor/

Step 4: Access Harbor

After the installation has succeeded, access Harbor web console on https://registry_domain.


Login with:

Username: admin
Password: as-set-in-harbor.yml


You should get to Harbor web dashboard.


With Let’s Encrypt SSL:


Step 5: Managing Harbor’s lifecycle

List running Harbor service containers:

$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
harbor-core         "/harbor/harbor_core"    core                running (healthy)
harbor-db           "/docker-entrypoint.…"   postgresql          running (healthy)   5432/tcp
harbor-jobservice   "/harbor/harbor_jobs…"   jobservice          running (healthy)
harbor-log          "/bin/sh -c /usr/loc…"   log                 running (healthy)>10514/tcp
harbor-portal       "nginx -g 'daemon of…"   portal              running (healthy)   8080/tcp
nginx               "nginx -g 'daemon of…"   proxy               running (healthy)>8080/tcp, :::80->8080/tcp,>8443/tcp, :::443->8443/tcp
redis               "redis-server /etc/r…"   redis               running (healthy)   6379/tcp
registry            "/home/harbor/entryp…"   registry            running (healthy)   5000/tcp
registryctl         "/home/harbor/start.…"   registryctl         running (healthy)  

You can use docker-compose to manage the lifecycle of Harbor. See examples below.

Stopping Harbor:

$ docker-compose stop
[+] Running 9/9
 ⠿ Container harbor-jobservice  Stopped                                                                                                                                                          0.2s
 ⠿ Container registryctl        Stopped                                                                                                                                                         10.2s
 ⠿ Container nginx              Stopped                                                                                                                                                          0.3s
 ⠿ Container harbor-portal      Stopped                                                                                                                                                          0.2s
 ⠿ Container harbor-core        Stopped                                                                                                                                                          0.3s
 ⠿ Container redis              Stopped                                                                                                                                                          0.2s
 ⠿ Container harbor-db          Stopped                                                                                                                                                         10.3s
 ⠿ Container registry           Stopped                                                                                                                                                         10.2s
 ⠿ Container harbor-log         Stopped                                                                                                                                                         10.3s

Restarting Harbor after stopping:

$ docker-compose start
[+] Running 9/9
 ⠿ Container harbor-log         Started                                                                                                                                                          0.5s
 ⠿ Container harbor-portal      Started                                                                                                                                                          0.7s
 ⠿ Container registryctl        Started                                                                                                                                                          0.6s
 ⠿ Container redis              Started                                                                                                                                                          1.0s
 ⠿ Container harbor-db          Started                                                                                                                                                          0.9s
 ⠿ Container registry           Started                                                                                                                                                          0.9s
 ⠿ Container harbor-core        Started                                                                                                                                                          0.5s
 ⠿ Container harbor-jobservice  Started                                                                                                                                                          0.6s
 ⠿ Container nginx              Started                                                                                                                                                          0.6s

Updating Harbor’s configuration:

To change Harbor’s configuration, first, stop existing Harbor instance and update harbor.yml. Then run prepare script to populate the configuration. Then re-create and start Harbor’s instance:

docker-compose down -v
vim harbor.yml
docker-compose up -d

When Harbor is installed with Notary, Clair and chart repository service:

docker-compose down -v
vim harbor.yml
./prepare --with-notary --with-clair --with-chartmuseum
docker-compose up -d

For troubleshooting, check the log file of container service in question in directory /var/log/harbor.

tail -n 100 /var/log/harbor/clair.log

Visit Harbor user guide page to learn more on usage.

More Harbor guides:


Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.