Before you can deploy a registry, you need to install Docker on the host. A registry is an instance of the registry image, and runs within Docker.
Install docker service with bellow commands.
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo dnf install -y docker-ce --nobest systemctl enable --now docker dockerstatus=`systemctl status docker | grep "active (running)"` echo "Docker Service Status = $dockerstatus"
Run a local registry
docker pull registry docker run -d -p 5000:5000 --restart=always --name registry registry:2
Secure Docker Private Registry
By default, Docker node uses a secure connection over TLS to upload or download images to or from the private registry. You can use TLS certificates signed by CA or self-signed on Registry server.
Here, I will use a self-signed certificate for securing Docker Registry. Let’s create a self-signed certificate using the following command.
[root@registry ~]# mkdir -p /certs [root@registry ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /certs/ca.key -x509 -days 365 -out /certs/ca.crt Generating a 4096 bit RSA private key ............................................++ .....................................................................................................++ writing new private key to '/certs/ca.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:LK State or Province Name (full name) []:Western Province Locality Name (eg, city) [Default City]:Colombo Organization Name (eg, company) [Default Company Ltd]:Sysadmin.lk Organizational Unit Name (eg, section) []:IT Common Name (eg, your name or your server's hostname) []:dockerhub.sysadmin.lk Email Address []:inbox@sysadmin.lk
Start Docker registry container with certificate information.
docker run -d -p 443:5000 --restart=always --name dockerhub -v docker-registry:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/ca.crt -e REGISTRY_HTTP_TLS_KEY=/certs/ca.key registry:latest
Allow ports on Firewall service
If your Docker Registry is on CentOS 7,8 or 9
[root@registry ~]# firewall-cmd --permanent --add-port=80/tcp [root@registry ~]# firewall-cmd --permanent --add-port=443/tcp [root@registry ~]# firewall-cmd --reload
Set up Authentication for a Private Registry
Docker allows us to store the images locally on a centralized server, but sometimes, it’s necessary to protect the images from external abuse. In that case, we’ll need to authenticate the registry with the basic htpasswd authentication.
Let’s first create a separate directory to store the Docker registry credentials and let’s run an httpd container to create a htpasswd protected user with a password:
docker run --entrypoint htpasswd httpd:2 -Bbn Prabath Password@123 > /usr/certs/users
Now, let’s run the same Docker registry container using the auth/htpasswd authentication file:
docker run -d -p 443:5000 --restart=always --name dockerhub -v docker-registry:/var/lib/registry -v /usr/certs:/usr/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/usr/certs/ca.crt -e REGISTRY_HTTP_TLS_KEY=/usr/certs/ca.key -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/usr/certs/users registry: latest
Since the Docker registry is running with the basic authentication, we can now test the login using:
$ docker login localhost-u Prabath -p Password@123 WARNING! Using --password via the CLI is insecure. Use --password-stdin. WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
Create and upload a Docker Image to a Private Registry server
NOTE: If the image name does not match with given format then docker push or pull command will try to upload or download the image from the public registry, not from the private registry.
To rename the docker image use docker tag command.
root@build:~# docker tag nginx:v1 dockerhub.sysadmin.lk/nginx:v1
Upload a Docker Image
Depends on the communication mode (Secure or Non-Secure) of Docker Registry, follow any one of the below methods.
Non-Secure (Plain Http Registry)
Edit/Create the file “daemon.json” in “/etc/docker/” directory.
root@build:~# vi /etc/docker/daemon.json { "insecure-registries" : ["dockerhub.sysadmin.lk"] }
If you are using Secure (Self-signed) certificate, you have to follow below steps.
mkdir /etc/docker/certs.d/dockerhub.sysadmin.lk/ && cd /etc/docker/certs.d/dockerhub.sysadmin.lk/ scp root@dockerhub.sysadmin.lk:/usr/certs/ca.crt .
In both cases, you would need to restart the Docker engine service.
systemctl restart docker
now you can upload a Docker Images as below.
root@build:~# docker push dockerhub.sysadmin.lk/nginx:v1
Download the docker image to private registry server using the following command.
[root@deploy ~]# docker pull dockerhub.sysadmin.lk/nginx:v1
Docker Registry API – Listing
At the time of writing, V2 is the current version of the Registry API. Let’s explore how to use it to list images and tags from a remote registry.
Let’s assume we have a registry deployed at the URL https://my-registry.io. We’ll use curl to execute the HTTP requests.
$ curl -X GET my-registry.io/v2/_catalog
{"repositories":["centos","ubuntu"]}
We should note that authentication may be required to access certain repositories if it has been enabled. In such cases, we can pass in the username and password as parameters to the curl command using the -u option.
$ curl -u user:password -X GET my-registry.io/v2/_catalog
{"repositories":["centos","ubuntu"]}
Listing Tags
The method to list tags is similar to the v2 API. However, the output is different in this case:
$ curl -X GET https://registry.hub.docker.com/v1/repositories/baeldung/mesos-marathon-demo/tags
[{"layer": "", "name": "32"}, {"layer": "", "name": "33"}, {"layer": "", "name": "34"}]
As we can see, instead of a single array of tags, we have an array of objects. Each object includes the name of the tag and the layer ID of the image.
If needed, we can convert the response to an array. To do so, let’s pipe the output into the jq command and parse the JSON:
$ curl -s GET https://registry.hub.docker.com/v1/repositories/baeldung/mesos-marathon-demo/tags | jq -r '[.[].name]'
[
"32",
"33",
"34"
]
Let’s understand the jq command and expressions used here:
- The -r flag returns the output as raw text.
- The expression .[].name returns the name property from each object from the curl output.
- The square brackets [] around the expression indicate that we want to collect the output in an array.
Finally, the -s flag used with the curl command is required to suppress the progress bar output.