Clean Up Your Docker Registry

Delete unused digests of docker images and save space

Mahesh Chinthaka
Better Programming

--

cleaning docker registry

If you’re using your docker registry to push continuous updates you’ve probably noticed that the disk mount space for the registry is gradually growing.

It looks like it’s time to have a registry clean up. Here’s how to do it.

First, Let’s Get Familiar With the Jargon

One docker image can have multiple tags. Each image has a digest, which is a unique value. When you do continuous pushes (with updated content) to the same image in the registry, the image in the registry will end up with multiple digests.

A tag is composed of several layers. The list of the layers for that particular digest is called a manifest. There is a corresponding blob for each layer. There can also be layers which are not used by any of the tags — those are called abandoned or unused layers. Those corresponding blobs are also unused. We can delete them to gain some space on the disk.

images, tags, layers, and blobs

As you can see, the layers are shared among manifests (tags) — each manifest maintains a reference to the layer. As long as a layer is referenced by one manifest, it cannot be garbage collected.

Digests of a docker repo can be found under RepoDigests after a docker inspect command.

eg : docker inspect my.docker.registry.com:5000/ubuntu:latest

"RepoDigests": ["my.docker.registry.com:5000/ubuntu@sha256:74a1b5f5c5d771cf3570fa0f050e0c827538b7fe1873bc88b85d56818df3f2bc"],

Garbage Collector

The garbage collector is the one who actually deletes unused/abandoned/orphaned blobs.

Garbage collection is the process of removing blobs from the filesystem when they are no longer referenced by a manifest. Blobs can include both layers and manifests.

In order for garbage collector to delete the blobs, we need to make those blobs orphaned. We can achieve that with two methods.

  1. Using v2 registry REST API
  2. Manually deleting in filesystem using ‘rm’ command.

Method 01: Using registry REST API

For this, you need to know the docker image name and the digest you want to delete.

Invoke rest API

curl -v -X DELETE http://registryhost:reigstryport/v2/${docker_image_name}/manifests/${digest}

eg : curl -vk -X DELETE https://my.docker.registry.com:5000/v2/mytestdockerrepo/manifests/sha256:66675d81b9bd5eafc105832b78abb91cab975bbcf028ca4bce4afe73f66914ee

You should get a 202 Accepted for a successful invocation.

Then run garbage collector

docker exec registry bin/registry garbage-collect --dry-run /etc/docker/registry/config.yml

registry — registry container name.

Method 02: Deleting in the file system

You need to delete two dirs.

rm -r <root>/v2/repositories/${name}/_manifests/tags/${tag}/index/sha256/${hash}rm -r <root>/v2/repositories/${name}/_manifests/revisions/sha256/${hash}

Here <root> means the the registry mount location where this registry container stores all the data in the file system.

eg : /var/lib/registry/docker/registry

If you have mounted this to one of your disks in host machine you can delete from there. Otherwise you will have to attach to the registry container by using docker attach command and delete directories.

Then run garbage collector:

docker exec registry bin/registry garbage-collect --dry-run /etc/docker/registry/config.yml

Please note that when using Method 01, registry container should have

REGISTRY_STORAGE_DELETE_ENABLED=true

You can also pass that as a environmental variable with -e tag when starting the container or inside your dockerfile.

If you are using Method 02, at the time of deleting those dirs the docker registry should be in read-only mode. Nobody should push to registry.

--

--