Thứ Sáu, 26 tháng 11, 2021

How to maintain a Private Docker Registry?

 In this article, I will explain about Docker Registry and guide you step by step on how to create and maintain your own Private Docker Registry. Peek into my Docker Basics article if you are a newbie to Docker.

Docker Registry is a place where you can store your own Docker images and distribute it to others. A Docker Registry is organized into Docker Repositories. In a Docker Repository, you can maintain specific versions of a Docker Image. DockerHub is the default Docker engine’s image store. DockerHub is public and anyone can pull the images which are stored in DockerHub. Other than DockerHub there are more paid public Docker registries available. Some of them are listed below.

  1. Google Container Registry (GCR)
  2. Amazon Elastic Container Registry (ECR)
  3. Azure Container Registry (ACR)

Let’s start to create your own Private Docker Registry in localhost..
*In order to begin, you need to have Docker installed on your computer.

Setting up Docker Registry

Pull Docker Registry image from DockerHub

$ docker pull registry

This command will pull the latest docker image from docker registry.

Let’s now configure the registry image and run it.

$ docker run -d -p 5000:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true --name localregistry registry

This command will configure to start the docker registry container on localhost port 5000. The base image used here is registry(we just pulled). Container name will be localregistry. In order to delete images on your Private Registry, we need to enable the deletion enabled configuration. In this tutorial, we are pulling, pushing, and deleting the images which are on the localregistry container. For this reason, I enabled deletion in my configuration. If the localregistry container launch is successful, it will return the container ID on the console.

You can confirm it by running the command below and it will provide you with the container status.

$ docker ps

Push some images to Docker registry

Let’s pull a few images from DockerHub and push them to your Private Docker Registry. For the demonstration, I will download two versions of Ubuntu Images and the latest version of Nginx Image.

$ docker pull ubuntu:18.04
$ docker pull ubuntu:19.10
$ docker pull nginx

Now I am going to tag all the images which were pulled from the DockerHub.

$ docker tag ubuntu:18.04 localhost:5000/ubuntu:18.04
$ docker tag ubuntu:19.10 localhost:5000/ubuntu:19.10
$ docker tag nginx:latest localhost:5000/nginx:latest

An explanation of “localhost:5000/ubuntu:18.04”
a) 
localhost:5000- the host of your private docker registry
b) ubuntu- the repository name
c) 18.04- the tag to identify the version

$ docker push localhost:5000/ubuntu:18.04
$ docker push localhost:5000/ubuntu:19.10
$ docker push localhost:5000/nginx:latest

For every successful push, you will see the sha value of each image on the console.

a) List the available repositories

$ curl http://localhost:5000/v2/_catalog

b) List the available tags inside a repository(ubuntu)

$ curl http://localhost:5000/v2/ubuntu/tags/list

Delete Images from the Private Docker Registry

Let's remove ubuntu 18.04 tag and the image from the Docker Registry. In order to do that we need to get the Docker-Content-Digest of the tag. Once you execute the command below, the sha value for ubuntu 18.04 tag will be returned to the console. You may copy that output.

$ curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET http://localhost:5000/v2/ubuntu/manifests/18.04 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'

Now let's delete the image by using the Docker-Content-Digest ID which was returned.

$ curl -v -X DELETE http://localhost:5000/v2/ubuntu/manifests/<sha_value_you_received_from_the_previous_command>

Once you run this command you will receive a successful reply(status code 202).

Now we need to run the Docker Garbage Collector to remove the image completely from the file system. From this step, you will be able to reduce the storage used.

$ docker exec localregistry bin/registry garbage-collect --delete-untagged /etc/docker/registry/config.yml

You will see that all the layers will be listed and only the related layers will get selected to be deleted.

PLEASE NOTE in registry version 2.7.1 :- At this moment you have successfully deleted your image. But if you again push the same image(Ubuntu 18.04) to your local Docker Registry, you will see a reply saying the image layers still exist. In order to avoid this you need to restart you Docker Registry.

$ docker restart localregistry

Now you can push the same image and you will see that its getting pushed.

Note:

The v2 registry doesn't allow deleting only certain tags from an image

This means that the entire image is deleted. Deletion of tags is in an open PR for a future version of the Registry (https://github.com/docker/distribution/pull/2169)

What this means in regards to this question is that the proper method is to delete the image from the repo list is exactly as you assumed. Remove it from disk. (Such as rm -r v2/repositories/myimage where myimage is the image name that you deleted via API.)

It will then be removed from the repo list in _catalog and you're finished with your deletion process. There is no need to restart anything like another answer mentioned.

When the ability to delete specific tags from the registry is added, then this procedure will change. For now it's all or nothing.

Reference:

https://forums.docker.com/t/delete-repository-from-v2-private-registry/16767/5

https://github.com/docker/distribution/pull/2169

https://docs.docker.com/registry/spec/api/

This mechanism works very well in docker registry v2.7.0 onwards. If you are using an older docker registry(v2.6.0) you won't be able to free up a considerable amount of disk space. If you push a different image with an already existing image tag, old versions of docker registry’s(v2.6.0) garbage cleaning won't remove the older image layers. As a result, you will experience that your storage size will grow.

Now I hope that you will be able to maintain your Private Docker Registry by following this tutorial. See you all with another Write-up!

Read More