DCA – 06 – Docker Registry

Jarret B

Well-Known Member
Staff member
May 22, 2017
Reaction score
A Docker Registry is a local system that acts as a hub to upload and download Docker images. The Docker Registry is a repository of the images that you made or downloaded.

The Docker Registry will be available to all systems on the network with access, as well as having a key and the user knowing the username and password.

NOTE: Before beginning this article, you may want to delete any existing images you have on your Docker Server. We will use Server1 and Server2 in this article. Make sure they are both empty of images if you want.

Creating a Docker Registry Security

We can secure the Registry with keys and passwords, or it can be unsecured. We will make a secured Registry as an example.

Since we will deal with keys, the system will need 'openssl'. Make sure you have installed it if you haven’t already installed it.

We'll need to create two folders in our HOME folder for the certification and password authentication. Perform the following two commands:

mkdir cert
mkdir pass

The 'cert' folder will contain the certificates for the systems that will need authentication from the Docker Registry. The 'pass' folder will contain the username and password information to log into the Registry.

Let's make a self-signed certificate to place into the 'cert' folder:

openssl req -newkey rsa:4096 -nodes -sha256 -keyout cert/registry.key -x509 -days 365 -out cert/registry.crt -subj "/CN=registry.com" -addext "subjectAltName=DNS:registry.com"

The command shows we are requesting (req) a new key (-newkey). The new key is RSA encrypted (rsa:4096). We do not use a passphrase (-nodes) with a SHA256 checksum (-sha256). The system writes the private key out to the file 'cert/registry.key' (-keyout). We then specify we want a self-signed certificate (-x509). It is possible for us to specify the number of days that the certificate is valid (-days 365), so the certificate expires in 1 year. The certificate is output to 'cert/registry.crt' (-out). Finally, we are calling our domain for the Docker Registry as 'registry.com'.

We can name the files whatever you wish, as well as the Docker Registry domain, except for 'htpasswd' should stay the same.

The command should complete without errors. If you mistype something and need to re-run the command, delete any existing files in 'cert' first.

You should be able to look in the 'cert' folder and see that the key and certification exist.

Next, get the IP Address of the server that is to be the Registry Server. In my case, the IP Address of Docker1 is ''. With this address, you need to edit the '/etc/hosts' file and add the line:

The line will need to be added to the 'hosts' file on any systems that will access the Registry. Be sure to add the line to Docker2.

Now, we need to use the certificate on the Docker Registry Server. First, create the folder '/etc/docker/certs.d/registry.com:5000' with the command:

sudo mkdir -p /etc/docker/certs.d/registry.com:5000

You can change into the folder with the command 'cd /etc/docker/certs.d/registry.com\:5000'. The certificate we created needs to be copied into this folder with the command:

sudo cp ~/cert/registry.crt ca.crt

We need to set up our user and password authentication for our Registry. Before we create the authentication hash, we need to install the Registry.

On Our Registry system, switch back to the HOME folder with the command 'cd ~'. We can get the Registry Image with the command:

docker pull registry:2

Once it pulls the image, we can create a username and password hash with the command:

docker run --entrypoint htpasswd registry:2 -Bbn user1 password > pass/passwd1

NOTE: If you get an error about 'htpassword' not being found, you need to remove the 'registry:2' image and pull 'registry:2.7.0'. Change any references of 'registry:2' to 'registry:2.7.0'. Sometimes, there is an error in 'registry:2'.

If you used 'registry:2.7.0, then the command is:

docker run --entrypoint htpasswd registry:2.7.0 -Bbn user1 password > pass/passwd1

The command will generate the file 'pass/passwd1', which, if you 'cat' it, you can see the username and the hash created for the password.

If you wanted to add more names and passwords to the file, change the username and password, then make the greater than redirector to a double greater than symbol, such as:

docker run --entrypoint htpasswd registry:2 -Bbn user2 password >> pass/passwd1

Now that we set the security, we can deploy our Registry.

Deploy Registry

We need to run the 'registry' image and associate all the certificates and keys with it to make it secure. The container will not be interactive, but we can push images to it and pull the images back out.

To start the container, we use the command:

docker run -d -p 5000:5000 -v /home/jarret/cert:/cert -e REGISTRY_HTTP_TLS_CERTIFICATE=/cert/registry.crt -e REGISTRY_HTTP_TLS_KEY=/cert/registry.key -v /home/jarret/pass:/pass -e REGISTRY_AUTH=htpasswd -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/pass/passwd1 registry:2

NOTE: Be sure you change the image name if needed to 'registry:2.7.0'.

Now, if we run 'docker images', we should only see the 'registry' with the tag of '2' or '2.7.0'. Unless you kept all your images, there could be more if you didn't delete the ones you had before starting this article.

To place an image in the Registry, it must be local to the Registry Server.

Pushing an Image into the Registry

Let's grab a small image to use that we can place into the Registry, 'hello-world'. Execute the command 'docker pull hello-world'.

Once the system downloads the image, it is ready to be pushed into the Registry.

To access the Registry, you need to log in to get credentials. The login command is:

docker login registry.com:5000

Always make sure you specify the port previously set up. If you do not specify a port, the default is 443.

Now, we need to tag the image we need to push with the command:

docker tag hello-world registry.com:5000/hello-world

If you run the command 'docker images', you will see the regular 'hello-world' as well as the tagged one.

We can now push the image to the Registry with the command:

docker push registry.com:5000/hello-world

We can see the output from the command in Figure 1.

Figure 1.JPG


Now that the image is in the Registry, we no longer need it locally. The following two commands can remove the two images for 'hello-world':

docker rmi registry.com:5000/hello-world
docker rmi hello-world

In my case, running 'docker images' only shows the 'registry:2.7.0'.

Now that we have an image in the Registry, we can pull it from other systems.

Pulling an Image from a Registry

We can test that the image is present in the Registry by pulling it into the local system. Perform the command:

docker pull registry.com:5000/hello-world

Running 'docker images' shows the newly downloaded image named 'registry.com:5000/hello-world'.

You can run the image to verify that it is indeed 'hello-world':

docker run registry.com:5000/hello-world

So, we can easily pull from the Registry on the local system. What we need to do is also pull images from the Registry from other systems on the network. This I will do from my Docker2 system.

Before going to 'Docker2', we need to copy the certificate to 'Docker2'. On 'Docker1' switch to the folder '/etc/docker/certs.d/registry.com:5000'. We need to copy the 'ca.crt' file to 'Docker2' with the command:

sudo scp ca.crt user1@docker2:/home/user1

NOTE: 'Docker2' must have 'openssh-server' installed to perform the 'scp' command. If you do not want to install openssh, then you'll need to copy the file manually with an external device or a network share.

Instead of 'user1', make sure you specify a username that exists and then a username folder that the user can access.

On 'Docker2', you'll need to create the folder '/etc/docker/certs.d/registry.com:5000' and copy the file 'ca.crt' to the folder you created.

Run 'ls -l' to verify the owner of the 'ca.crt' file is owned by 'root'. If not, use the command 'sudo chown root:root ca.crt'.

Next, add the line to the '/etc/hosts' file if you already have not done it. When done, test it by pinging the 'registry.com' system. It should resolve 'registry.com' to your server's name and IP Address. Add the line ' registry.com'.

Now, you need to log in to the Registry Server with the command:

docker login registry.com:5000

Use the credentials you set up for the username and password.

The Registry Server should authenticate you and you can pull images from it. So, from Docker2, use the command to pull 'hello-world':

docker pull registry.com:5000/hello-world

The image should pull from the Registry, and you can run the image to verify it works.

You now have an operational Docker Registry Server.


Be aware of the steps in this process to make a Registry. Practice it a few times, which may require setting up a snapshot in VirtualBox to be sure that you can perform all the processes to make this work. Practice creating and distributing the key and making a password hash.

Set up the Docker Registry a few times to be comfortable with the steps. Push and pull a few images to be familiar with it. Make sure you pull locally and from a different system.

Having a Docker Registry can be valuable within a company to keep all the required images local and at a specific version.