This tutorial provides a step-by-step guide to setup Harbor with a Let’s Encrypt certificate using Certbot
Requirements
- Linux machine (tested with Ubuntu 20.04)
- A public domain pointing to your Linux machine
- Port 80/443 is reachable from the outside
- Docker
- Docker Compose
Certbot / Let’s Encrypt
First, we need to install Certbot to create Let’s Encrypt certificates on our machine. On Ubuntu, this can be easily done by using snap:
$ snap install certbot --classic
Afterward, we are able to create a new certificate for our Harbor domain by using the standalone mode of Certbot and add the desired domain as a parameter. When running Certbot for the first time, it will ask for a valid email address and accept the terms of service before creating the certificate.
$ certbot certonly --standalone -d registry.example.com
Once the command has been completed, it should provide us the following output:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/registry.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/registry.example.com/privkey.pem
Your certificate will expire on 2021-04-21. To obtain a new or
tweaked version of this certificate in the future, simply run
certbot again. To non-interactively renew *all* of your
certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Finally, we can find the certificate files in the folder of the related domain at /etc/letsencrypt/live.
$ ls /etc/letsencrypt/live/registry.example.com
README cert.pem chain.pem fullchain.pem privkey.pem
Harbor
Now we can continue with installing Harbor on the machine. Let’s go to the Harbor GitHub Releases page, download the latest installer and extract the archive:
$ wget https://github.com/goharbor/harbor/releases/download/v2.1.3/harbor-online-installer-v2.1.3.tgz
$ tar xvf harbor-online-installer-v2.1.3.tgz
To configure the Harbor instance, we can create a copy of the extracted Harbor configuration template and open it with an editor:
$ cd harbor
$ cp harbor.yml.tmpl harbor.yml
$ vim harbor.yml
The configuration file provides a lot of properties to configure and customize the Harbor instance. For a minimalistic installation, it’s enough to change the following values:
# Change the hostname to your domain configured earlier
hostname: reg.mydomain.com
# Keep the http and https port configuration, but change the path of
# the certificate files to the Let's Encrypt certificate
http:
port: 80
https:
port: 443
certificate: /your/certificate/path
private_key: /your/private/key/path
# Change the admin password to something more secure
harbor_admin_password: Harbor12345
# Change the database password to something more secure
database:
password: root123
Once the configuration has been adapted, Harbor is ready to be deployed using the install script:
$ ./install.sh
...
✔ ----Harbor has been installed and started successfully.----
Finally, let’s open the domain of the Harbor instance in a browser and check the result. We should see the Harbor login page secured by a valid certificate.
Certificate Renewal
Certbot creates a Cronjob/Timer to renew the requested certificates automatically before they expire.
$ systemctl list-timers
Fri 2021-01-22 07:10:00 CET 5h 57min left Thu 2021-01-21 22:20:02 CET 2h 52min ago snap.certbot.renew.timer snap.certbot.renew.service
Currently, this renewal will fail, because the Nginx container of Harbor is already using port 80 on the machine. This port is needed by Certbot to renew the existing certificates.
Fortunately, Certbot provides Pre-/Post-Hooks which can be created to stop/start running services before/after renewing the certificates.
These hooks can be created at /etc/letsencrypt/renewal-hooks/{pre|post}. Let’s create a script to stop the Nginx container of Harbor before running the renew task:
$ vim /etc/letsencrypt/renewal-hooks/pre/harbor.sh
Insert the following content:
#!/bin/bash
/usr/bin/docker stop nginx
Make the script executable:
$ chmod 755 /etc/letsencrypt/renewal-hooks/pre/harbor.sh
Now we also have to create the post-hook script to copy the new renewed certificates to Harbor’s data directory and start the Nginx container again. Create the post-hook script and add the following content:
$ vim /etc/letsencrypt/renewal-hooks/post/harbor.sh
Insert the following content:
#!/bin/bash
cp -f /etc/letsencrypt/live/registry.example.com/fullchain.pem /data/secret/cert/server.crt
cp -f /etc/letsencrypt/live/registry.example.com/privkey.pem /data/secret/cert/server.key
/usr/bin/docker start nginx
Make the script executable:
$ chmod 755 /etc/letsencrypt/renewal-hooks/post/harbor.sh
Keep in mind to change the paths according to your setup. The configured data directory for Harbor can be found in the harbor.yml file.
To check if the scripts are configured correctly, we can test the renewing of the certificate by using Certbot’s renew command in dry-run mode. We should see the following output:
$ certbot renew --dry-run
...
Running pre-hook command: /etc/letsencrypt/renewal-hooks/pre/harbor.sh
Output from pre-hook command harbor.sh:
nginx
...
Running post-hook command: /etc/letsencrypt/renewal-hooks/post/harbor.sh
Output from post-hook command harbor.sh:
nginx
Now the setup is completed. The Harbor instance should be up and running and the Let’s Encrypt certificate should be automatically renewed.
Top comments (0)