After using Docker in development, you might want to put your application into production. Depending on your need, you might not want to push your private Docker images for your application to the Docker Hub, but have a private registry instead.
Docker has been providing the private registry on GitHub for a long time and it works pretty well. The downside is that it doesn't provide security features like RBAC.
That's where 3rd party solutions kick in.
We've been evaluating several solutions like AWS EC2 Container Registry (ECR) and others.
In the end, we're now running on Harbor, an Open Source registry server from VMware build around the aforementioned Docker registry.
Harbor is being developed in Golang and provides these key features:
First, here are some screenshots from harbor, starting with the admin dashboard:
Beside user self registration (can be turned off), the Admin can invite users:
Admins can create projects:
You can see all images for a particular project:
The Harbor User Guide shows some more screenshots.
The goal of this post is to get a Harbor instance running on DigitalOcean with HTTPS enabled using Docker Machine.
I'm assuming that you're familiar with Docker Machine basics and have it up and running. Furthermore, you'll need to have the Docker engine and Docker Compose installed which are required by Harbor for deployment.
And because we want to enable HTTPS, you should have grabbed a certificate from DigiCert or somewhere else.
First, clone the latest Harbor version from GitHub:
$ git clone git@github.com:vmware/harbor.git
Inside the Deploy
folder there are several configuration options within the harbor.cfg
file.
There are two options you have to configure at a minimum:
hostname = harbor.yourdomain.com
ui_url_protocol = https
Inside the Deploy/config/nginx
folder there are two nginx configuration files named nginx.conf
and nginx.https.conf
.
The file being used by Harbor is nginx.conf
. Because we want to use HTTPS, we need to get Harbor use nginx.https.conf
:
$ mv nginx.conf nginx.conf.bak
$ cp nginx.https.conf nginx.conf
Then we have to modify the new nginx.conf
and replace the two occurrences of harbordomain.com
with our own Harbor URI, e.g. harbor.yourdomain.com
.
Regarding the certificate, there a two options: Use the cert filename from DigiCert (in my case) and the server.key
file and modify the nginx.conf
accordingly or rename the certificate to harbordomain.crt
.
Either case, you have to copy the cert file and the key file from your Certificate Signing Request to the Deploy/config/nginx/cert
folder.
The SSL settings within the nginx.conf
should look like this:
# SSL
ssl_certificate /etc/nginx/cert/harbor_yourdomain_com.pem;
ssl_certificate_key /etc/nginx/cert/harbor_yourdomain_com.key;
Next, from the bash, run the following command within the Deploy
folder:
$ ./prepare
This will copy the settings to their appropriate destinations.
With that done, lets create our Docker Machine instance for deployment. To create a DigitalOcean Droplet using Docker Machine, we need an API access token which can be created at the DigitalOcean Website (Azure or AWS are similar):
Copy your token and keep it safe, you won't see it again at the DigitalOcean website.
Now, back to the bash, we can create a Droplet using Docker Machine - make sure it has at least 2GB of RAM:
$ docker-machine create --driver digitalocean --digitalocean-access-token <yourtokenfromabove> --digitalocean-size 2GB harbor.yourdomain.com
Docker Machine provides more options for the --driver
like the region. Just read the Docker Machine Driver Documentation for more.
When the Droplet is up and running (this should take only a few seconds), activate that particular Docker Machine instance:
$ eval $(docker-machine env harbor.yourdomain.com)
Because we want to spin up the containers required by Harbor using Docker Compose, we have to copy the settings from the Deploy/config
directory first to our Docker Machine instance.
First, get the absolute path to the Deploy
directory (cd
first into it):
$ echo $PWD
The result should be something like this:
/home//src/harbor/Deploy
Now we create the exact same absolute folder structure (including the config
subfolder) inside the Docker Machine instance and copy the contents of our local Deploy/config
folder into it:
$ docker-machine ssh harbor.ỳourdomain.com 'mkdir -p /home/<yourusername>/src/harbor/Deploy/config
$ docker-machine scp -r ./config harbor.yourdomain.com:$PWD
Next, build the container images using Docker Compose (inside the Deploy
folder):
$ docker-compose build
And as a last step, we're spinning up our containers:
$ docker-compose up -d
Now you should be able to browse https://harbor.yourdomain.com
:
And of course, you can start pushing and pulling Docker images to and from your own registry now!
After creating a new project (I'm using test
here) and user as an Admin inside Harbor, you can push new images to Harbor like this:
$ docker tag customerservice:1.0.0 harbor.yourdomain.com/test/customerservice:1.0.0
$ docker login -u <username> -p <password> -e <email> harbor.yourdomain.com
$ docker push harbor.yourdomain.com/test/customerservice:1.0.0
And we're done!
As a side note: If you want to disable user self registration, apply this setting in harbor.cfg
:
self_registration = off
P.S.: This post mostly is a combination of the Harbor Installation Guide and the Deploying Harbor using Docker Machine Guide (the latter I contributed to the Harbor project, so I didn't just copy existing stuff).