Install Harbor Image Registry on Ubuntu 22.04|20.04

Posted on 81 views

A container registry can be defined as a repository or collection of repositories used to store and access container images. They can be used for container-based application development, saving developers valuable time to create and deliver cloud-native applications. They serve as intermediaries when sharing container images between systems.

Container images consist of libraries and system packages required to run an application. They provide several benefits to developers such as portability and agility. Container images can be created using tools like BuildahkanikoImg Image builder e.t.c. Once the container images have been developed, you need a place to save, share and access them later. A container registry provides storage for the images by uploading (pushing) and downloading them(pulling) to a remote system.

There are two main types of container registries:

  • Public registries: these are used by individuals and small teams that want to spin and run registries as fast as possible. These are less secure and might cause problems such as patching, privacy, and access control for large organizations.
  • Private registries: They offer advanced security features, providing the best way to incorporate security and privacy into enterprise container image storage. They can be hosted remotely or o-premise. The most popular Private Registries are Google Container Registry, Amazon Elastic Container Registry (ECR), and the Azure Container Registry.

Private container registries are preferred since they allow the organization to access the images internally in a more secure way. Multiple authentication systems put measures in place to verify the container images.

What is Harbor?

Harbor Container Image Registry is a free and open-source enterprise-class container registry used to store and distribute container images. It secures artifacts using policies and role-based access control. It also ensures that the images are scanned and free from vulnerabilities before signing them as trusted. Harbor was developed by VMware and later relinquished to the Cloud Native Computing Foundation(CNCF). Harbor evolved from Docker’s source code which was later enhanced to improve and eliminate security problems. Currently, it provides high performance and interoperability that helps users securely manage container images across cloud-native compute platforms such as Docker, Podman, Kubernetes e.t.c

The key features associated with Harbor are:

  • Manage Helm Charts: It helps manage Helm charts isolated by projects and controlled by RBAC.
  • Manage role by LDAP group: administrators can import an LDAP/AD group to Harbor and assign project roles to it.
  • Replicate projects: It supports image replication. It is possible to replicate repositories from one Harbor instance to another.
  • Role-Based Access Control: Users and repositories are organized into projects. Users can have different permissions for the images in different projects.
  • Vulnerability Scanning: It makes use of Clair to scan images regularly and warn users of any vulnerabilities.
  • Auditing: All the operations to the repositories are tracked.
  • RESTful API: It has RESTful APIs for most administrative operations, easy to integrate with external systems.
  • Graphical User Portal: where users can easily browse, search repositories, and manage projects.

Install Harbor Image Registry on Ubuntu 22.04|20.04

In this guide, we will comb through how to install Harbor Container Image Registry on Ubuntu 22.04|20.04

Harbor consists of 8 components that include:

  • Redis: an in-memory database used for storing login information.
  • PostgreSQL: the database used by the Harbor.
  • Beego: an open-source web app framework on which the Harbor web service is built and developed.
  • Chartmuseum: used to manage Helm Charts.
  • Docker: used for pushing and pulling docker images.
  • Helm: for managing Helm charts
  • Swagger-ui: used to call and test the RESTful API.

Begin by updating the server and installing the required packages:

sudo apt update && sudo apt -y full-upgrade
sudo apt install apt-transport-https ca-certificates curl software-properties-common vim git

Check if a reboot is required after system upgrade:

[ -f /var/run/reboot-required ] && sudo reboot -f

Step 1 – Install Docker and Docker Compose

Harbor is deployed as a docker container and requires Docker installed. To install Docker on Ubuntu 22.04|20.04, use the aid provided in the guide below:

Once installed, ensure that Docker is started and enabled:

sudo systemctl start docker && sudo systemctl enable docker

Add your system use to the Docker Group.

sudo usermod -aG docker $USER
newgrp docker

Verify the installation:

$ docker version
Client: Docker Engine - Community
 Version:           20.10.18
 API version:       1.41
 Go version:        go1.18.6
 Git commit:        b40c2f6
 Built:             Thu Sep  8 23:11:43 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
  Version:          20.10.18
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.6
  Git commit:       e42327a
  Built:            Thu Sep  8 23:09:30 2022
  OS/Arch:          linux/amd64
  Experimental:     false
  Version:          1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
  Version:          0.19.0
  GitCommit:        de40ad0

You should also have Docker Compose installed:

$ docker compose version
Docker Compose version v2.10.2

If not, you can install Docker Compose, using the guide below:

Step 2 – Download Harbor installer on Ubuntu 22.04|20.04

Harbor installer required docker-compose let’s install it.

curl -s|grep browser_download_url|grep docker-compose-linux-x86_64 | cut -d '"' -f 4|wget -qi -
chmod +x docker-compose-linux-x86_64
sudo mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
rm docker-compose-linux-x86_64.sha256

Confirm it works:

$ docker-compose version
Docker Compose version v2.10.2

Download the Harbor package by visiting the GitHub release page. It is also possible to pull the latest package from the command line with the command:

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

Once downloaded, extract the archive:

tar zxvf harbor-offline-installer-v*.tgz

Navigate into the directory:

cd harbor

Step 3 – Configure Harbor on Ubuntu 22.04|20.04

If you have a Fully Qualified Domain Name, you can generate SSL certificates for your domain name.

Using Let’s Encrypt SSL

Install certbot and request for Let’s Encrypt SSL:

sudo apt install certbot -y
sudo certbot certonly --standalone -d "" --preferred-challenges http --agree-tos -n -m "[email protected]" --keep-until-expiring

After this, you will have certificates at /etc/letsencrypt/live/

Using Self-signed certificates

  • It is also possible to generate and use Self-signed certificates. But this might cause a problem with unknown CA certificate when trying to connect to Harbor from Docker/Podman client.
mkdir -p certs
openssl req \
  -newkey rsa:4096 -nodes -sha256 -keyout certs/harbor.key \
  -addext "subjectAltName =" \
  -x509 -days 365 -out certs/harbor.crt

After this, copy the certificates to /etc/ssl/certs/;

sudo cp certs/harbor.* /etc/ssl/certs/

Once created, open the file for editing:

vim harbor.yml

In the file, make the desired configurations:

# port for http, default is 80. If https enabled, this port will redirect to https port
port: 80
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345

If you intend to run Harbor over HTTP alone (you do not have an FQDN), you need to comment out the below HTTPS-related configs:

# https related config
# port: 443
# certificate: /your/certificate/path
# private_key: /your/private/key/path

Example https configurations for self-signed certificates:

  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /etc/ssl/certs/harbor.crt
  private_key: /etc/ssl/certs/harbor.key

You can also configure the database password, with the number of maximum connections:

# Harbor DB configuration
  # The password for the root user of Harbor DB. Change this before any production use.
  password: root123
  # The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
  max_idle_conns: 100
  # The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
  # Note: the default number of connections is 1024 for postgres of harbor.
  max_open_conns: 900

Configure the storage path for Harbor as shown:

# The default data volume
data_volume: /data

It is also possible to use external storage such as azure, GCS, S3, swift, and OSS by uncommenting and modifying the below lines.

# Uncomment storage_service setting If you want to using external storage
# storage_service:
#   # ca_bundle is the path to the custom root ca certificate, which will be injected into the truststore
#   # of registry's and chart repository's containers.  This is usually needed when the user hosts a internal storage with self signed certificate.
#   ca_bundle:

#   # storage backend, default is filesystem, options include filesystem, azure, gcs, s3, swift and oss
#   # for more info about this configuration please refer
#   filesystem:
#     maxthreads: 100
#   # set disable to true when you want to disable registry redirect
#   redirect:
#     disabled: false

Once the modifications have been made, save the file and proceed as shown below.

Step 4 – Install Harbor on Ubuntu 22.04|20.04

Now you can install the Harbor Container Image Registry on Ubuntu 22.04|20.04 by executing the installer script as shown:

sudo ./

Sample Output:

[Step 0]: checking if docker is installed ...

Note: docker version: 20.10.18

[Step 1]: checking docker-compose is installed ...

Note: Docker Compose version 2.11.2

[Step 2]: loading Harbor images ...
915f79eed965: Loading layer [==================================================>]  37.77MB/37.77MB
53e17aa1994a: Loading layer [==================================================>]  8.898MB/8.898MB
82205c155ee7: Loading layer [==================================================>]  3.584kB/3.584kB
7ffa6a408e36: Loading layer [==================================================>]   2.56kB/2.56kB
1a2ed94f447f: Loading layer [==================================================>]  97.91MB/97.91MB
e031eb4548cd: Loading layer [==================================================>]   98.7MB/98.7MB
Loaded image: goharbor/harbor-jobservice:v2.6.0

Once complete, you should see this:


You can also view the running containers:

$ docker ps
CONTAINER ID   IMAGE                                  COMMAND                  CREATED          STATUS                             PORTS                                                                            NAMES
6e6bda2f1a5f   goharbor/harbor-jobservice:v1.10.14    "/harbor/harbor_jobs…"   21 seconds ago   Up 16 seconds (health: starting)                                                                                    harbor-jobservice
be4ba338c24d   goharbor/nginx-photon:v1.10.14         "nginx -g 'daemon of…"   21 seconds ago   Up 16 seconds (health: starting)>8080/tcp, :::80->8080/tcp,>8443/tcp, :::443->8443/tcp   nginx
05ce75a1f7dc   goharbor/harbor-core:v1.10.14          "/harbor/harbor_core"    21 seconds ago   Up 17 seconds (health: starting)                                                                                    harbor-core
baaeec02b7fb   goharbor/harbor-portal:v1.10.14        "nginx -g 'daemon of…"   21 seconds ago   Up 17 seconds (health: starting)   8080/tcp                                                                         harbor-portal
27719428c542   goharbor/harbor-registryctl:v1.10.14   "/home/harbor/start.…"   21 seconds ago   Up 18 seconds (health: starting)                                                                                    registryctl
d273aff2ee28   goharbor/redis-photon:v1.10.14         "redis-server /etc/r…"   21 seconds ago   Up 17 seconds (health: starting)   6379/tcp                                                                         redis
383433e6ec36   goharbor/registry-photon:v1.10.14      "/home/harbor/entryp…"   21 seconds ago   Up 17 seconds (health: starting)   5000/tcp                                                                         registry
e80e59840027   goharbor/harbor-db:v1.10.14            "/docker-entrypoint.…"   21 seconds ago   Up 17 seconds (health: starting)   5432/tcp                                                                         harbor-db
149ef8437374   goharbor/harbor-log:v1.10.14           "/bin/sh -c /usr/loc…"   21 seconds ago   Up 19 seconds (health: starting)>10514/tcp                                                        harbor-log

Step 5 – Access the Harbor Web UI on Ubuntu

Once installed, you can access the Harbor web interface using the URL http://domain_name or https://domain_name


Login using the credential defined on the Harbor config file. Once authenticated, you will see the below dashboard.


Create a User

From this dashboard, you can create a user by navigating to Administrator->Users then New user.


Provide the user details as shown.


Once created, the user will appear as shown and you can set them as admins by selecting the user and then click on Set as admin


Create New Harbor Registry

Navigate to the Administration menu and click on Registries-> NEW ENDPOINT


Harbor allows users to add other non-Harbor registries. The currently supported registries are Docker Hub, Docker registry, AWS Elastic Container Registry, Azure Container Registry, Huawei SWR, Gitlab,, Jfrog Artifactory, Artifact Hub (Support added in v2.0.4), Ali Cloud Container Registry, and Google Container Registry.

For this guide, I will demonstrate how to add the DockerHub registry. You need to provide the provider, name, URL of the Endpoint, access ID(username), and Access secret(password).


To verify if everything is okay, click on Test connection.


If the connection goes through, click Ok to add the registry. Once added, the registry will appear as shown.


Now we need to create a Replication under Replications->New Replication Rule to synchronize artifacts with Harbor.


Here, you need to provide the:

  • Name: lower case letters to specify the name
  • Description: information regarding your replication
  • Replication mode: This is the type of replication. It can be a Pull-based or push-based mode.
  • Source registry: the repository configured to synchronize with Harbor
  • Source filter: the repository you want to synchronize to your Harbor repository. For example nginx/latest on DockerHub
  • tag: Tag of the images that you want to synchronize.
  • Destination Namespace: Your project name
  • Trigger Mode: synchronization can be manually triggered or Scheduled

For example:


Once the details have been filled click on save. The new replication will be added as shown.


Now to trigger the synchronization manually, select the Replication and click Replicate


Now on your project, you should see replication.


Click on it and see the available image that has been synchronized.


Step 6 – Use Harbor Container Image Registry

Now you can pull and use the images in the Harbor Container Image Registry. If you used HTTP, you need to make the below adjustments on your Docker client.

sudo vim /etc/docker/daemon.json

Add the below lines:

"insecure-registries" : ["", ""]

Once the changes have been made, restart Docker:

sudo systemctl restart docker

You also need to ensure that Harbor DNS entry points to the Server IP:

$ sudo vim /etc/hosts

Login to Harbor

Now login to Harbor using the command with the syntax;

##For Docker
docker login 

##For Podman with HTTPS
podman login 

##For Podman with HTTP
podman login  --tls-verify=false

For example:

docker login

You can also provide the username and password with the command:

$ docker login --username=admin --password=Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /home/rocky9/.docker/config.json.
Configure a credential helper to remove this warning. See

Login Succeeded

Remember, you need to use –tls-verify=false for all Podman pull and push commands if you are using HTTP.

Pull a Container Image

To pull an image use the command with the syntax:

##For Docker
docker pull /library/image:tag

##For Podman with HTTP
podman pull /library/image:tag

##For Podman with HTTPs
podman pull /library/image:tag --tls-verify=false

For example:

docker pull

Sample Output:


Build and Push a Container Image

It is also possible to build and push container images. First, create a Dockerfile.

$ vim Dockerfile
FROM ubuntu:20.04
RUN apt-get update -y
ENV DEBIAN_FRONTEND=noninteractive 
RUN apt-get install -y gnupg apt-transport-https apt-utils wget
RUN echo "deb focal main" \
|tee /etc/apt/sources.list.d/notesalexp.list > /dev/null
RUN wget -O - | apt-key add -
RUN apt-get update -y
RUN apt-get install tesseract-ocr -y
RUN apt install imagemagick -y
ENTRYPOINT ["tesseract"]
RUN tesseract -v

Create the container images using the Dockerfile

##For Docker
docker build . -t tesseract:5

##For Podman
podman build . -t tesseract:5

Now tag the image to be pushed:

docker tag tesseract:5

Push an image:

docker push

Sample Output:


Verify if the image is available on Harbor.


This image can also be pulled and used to run containers.

Step 7 – Manage Harbor’s lifecycle

The Harbor containers can be stopped with the command:

$ docker compose stop
[+] Running 8/9
 ⠿ Container registryctl        Stopped                                   10.3s
 ⠿ Container harbor-jobservice  Stopped                                    0.5s
 ⠿ Container nginx              Stopped                                    0.5s
 ⠿ Container harbor-core        Stopped                                    0.4s
 ⠿ Container harbor-portal      Stopped                                    0.4s
 ⠿ Container redis              Stopped                                    0.6s
 ⠿ Container harbor-db          Stopped                                    0.6s
 ⠿ Container registry           Stopped                                    0.3s
 ⠋ Container harbor-log         Stopping                                  10.0s

To start the containers, use the command:

$ docker compose start
[+] Running 9/9
 ⠿ Container harbor-log         Started                                    0.6s
 ⠿ Container harbor-db          Started                                    2.3s
 ⠿ Container redis              Started                                    1.7s
 ⠿ Container registryctl        Started                                    2.0s
 ⠿ Container harbor-portal      Started                                    2.3s
 ⠿ Container registry           Started                                    2.3s
 ⠿ Container harbor-core        Started                                    0.6s
 ⠿ Container harbor-jobservice  Started                                    1.5s
 ⠿ Container nginx              Started                                    1.5s

To update the configurations, you need to stop the running Harbor instance:

$ docker compose down -v
[+] Running 7/8
 ⠇ Container registryctl        Stopping                                   8.9s
 ⠿ Container harbor-jobservice  Removed                                    0.4s
 ⠿ Container nginx              Removed                                    0.7s
 ⠿ Container harbor-core        Removed                                    3.3s
 ⠿ Container harbor-portal      Removed                                    0.3s
 ⠿ Container redis              Removed                                    0.6s
 ⠿ Container harbor-db          Removed                                    0.7s
 ⠿ Container registry           Removed                                    0.4s

Now make adjustments to your Harbor config:

vim harbor.yml

Once the desired adjustments have been made, run the below commands to start Harbor:

docker-compose up -d


That marks the end of this guide on how to install Harbor Container Image Registry on Ubuntu 22.04|20.04. You can now store and distribute container images securely with Harbor Container Image Registry. I hope this was significant.


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