While we have learned in a former recipe in this chapter how easy it is to upload our own images to the official Docker Hub, everything we put there will be exposed to the public. If you work on a private or closed-source project within a corporate environment or just want to test things out before publishing to everyone, chances are high that you would prefer your own, protected or cooperate-wide private Docker registry. Here in this recipe we will show you how you can set up and work with your own Docker registry that will be available in your own private network and which will be protected by TLS encryption and which will use user authentication so you can control exactly who can use it (push and pull images to and from it).
To complete this recipe, you will require a working installation of the CentOS 7 operating system with root privileges, a console-based text editor of your choice, and a connection to the Internet in order to facilitate the download of additional packages. In our example, we will install the Docker Registry on a server with the IP address 192.168.1.100
. Change the recipe's commands appropriately to fit your needs. You need to have set a FQDN for this server, otherwise the registry will not work. For simplicity, we will use the /etc/hosts
approach instead of setting up and configuring a DNS server (see Chapter 9, Working with Domains if you would like to do this instead). Also, you need an Apache web server on your Docker server running which must be accessible from your whole private network.
Complete all the following steps in this recipe with user root on every computer in your network you want to connect to the Docker registry!
192.168.1.100
, define the domain name of the Docker registry, which in our example will be dockerserver.home
(replace the dockerserver.home
part appropriately if you use a different domain name):echo "export DCKREG=dockerserver.home" >> ~/.bash_profile source ~/.bash_profile
192.168.1.100
appropriately):echo "192.168.1.100 $DCKREG" >> /etc/hosts
Common name
(for name; for example your name or your server's hostname) []:dockerserver.home
):cd; mkdir -p ~/certs; openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
mkdir -p /etc/docker/certs.d/$DCKREG:5000 cp ~/certs/domain.crt /etc/docker/certs.d/$DCKREG:5000/ca.crt cp ~/certs/domain.crt /etc/pki/ca-trust/source/anchors/docker-registry.crt update-ca-trust
cp ~/certs/domain.crt /var/www/html/docker-registry.crt
mkdir ~/auth; touch ~/auth/htpasswd docker run -d -p 5000:5000 --restart=always --name registry -v / root/certs:/certs -v /root/auth:/auth -v /reg:/var/lib/registry -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_AUTH=htpasswd registry:2
[::]:5000
, tls
):docker logs registry
johndoe
as the username and mysecretpassword
as the password for authentication. Change these two values to fit your needs. Repeat this command for every user account you want to have later for your users to login):cd; docker run -it --entrypoint htpasswd -v $PWD/auth:/auth -w /auth registry:2 -Bbc /auth/htpasswd johndoe mysecretpassword
docker restart registry
5000
possible:sed 's/80/5000/g' /usr/lib/firewalld/services/http.xml | sed 's/WWW (HTTP)/Docker registry/g' | sed 's/<description>.*</description>//g' > /etc/firewalld/services/docker-reg.xml firewall-cmd --reload firewall-cmd --permanent --add-service=docker-reg; firewall-cmd --reload
yum update && curl -sSL https://get.docker.com/ | sh
mkdir -p /etc/docker/certs.d/$DCKREG:5000 curl http://$DCKREG/docker-registry.crt -o /tmp/cert.crt cp /tmp/cert.crt /etc/docker/certs.d/$DCKREG:5000/ca.crt cp /tmp/cert.crt /etc/pki/ca-trust/source/anchors/docker-registry.crt update-ca-trust
docker login
busybox
:docker pull busybox
johndoe / mysecretpassword
. Leave the e-mail field blank):docker login $DCKREG:5000
docker tag busybox $DCKREG:5000/busybox
docker push $DCKREG:5000/busybox
$DCKREG:5000/busybox
on any other client set up to communicate to our repository. To get a list of all the available images, use (change the account information accordingly):curl https://johndoe:mysecretpassword@$DCKREG:5000/v2/_catalog
In this recipe we showed you how to set up your own Docker registry running in a Docker container on the server. It is very important to understand that you will need to configure a FQDN for your registry server because it is mandatory for the whole system to work.
So what did we learn from this experience?
We began by configuring the Docker registry's FQDN on every computer using the /etc/hosts
approach. Then we created a new certificate on the Docker registry server which will be used to communicate securely using TLS encryption between clients and registry. Next we installed the new generated certificate on the httpd
server, so it is accessible to all the clients later; also in a specific Docker directory to make it accessible for Docker as well; and in the default trusted certificate location of the server where we also rebuilt the certificate cache for this server. Afterwards, we used the docker run
command to download, install, and run our new Docker registry in a docker container itself on this server. We provided a list of parameters to configure TLS encryption and user authentication.
In the next step, we attached to the registry to create new htpasswd
accounts. You can repeat this step whenever you need new accounts for your registry. Don't forget to restart the registry container afterwards. Next, on every client we want to make communications to our new Docker registry, we need to install the server's certificate also in the same places as on the server itself; thus we downloaded it from the HTTP source implemented previously and copied it to the various locations. To test things out on the client, next we connected to the official Docker Hub to download a random image we wanted to push to our own registry in the next step. We downloaded the busybox
image to our own image cache and afterwards switched to connecting to our new private Docker registry. Before we could upload the image to the new location, we had to give it a proper tag that fitted the new server name and then we were able to push the image to our new Docker registry. The server is now available at port 5000 in the complete network. Remember that, if you don't want to use your own registry any more on the clients, you can always switch back to the official docker
repository using docker login
.
There is so much more to learn about Docker. In the recipes of this chapter we only scratched the surface of the Docker platform. If you want to learn more about it, consider going to https://www.Packtpub.com and check out one of the many titles available at this website about it.