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:
- Access Control: RBAC (Role Based Access Control) is provided. User management can be integrated with existing enterprise identity services like AD/LDAP.
- Audit: All access to the registry are logged and can be used for audit purpose.
- GUI: User friendly single-pane-of-glass management console.
- Project based approach to separate images and access to them
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 firstname.lastname@example.org:vmware/harbor.git
Deploy folder there are several configuration options within the
There are two options you have to configure at a minimum:
hostname = harbor.yourdomain.com ui_url_protocol = https
Deploy/config/nginx folder there are two nginx configuration files named
The file being used by Harbor is
nginx.conf. Because we want to use HTTPS, we need to get Harbor use
$ 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.
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
Either case, you have to copy the cert file and the key file from your Certificate Signing Request to the
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
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:
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
$ 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
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
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).