Tag: registry

Delete docker images from docker registry

Delete docker images from docker registry

Steps

Get Digest by pulling image

Use docker pull command can get image digest

docker pull registry.example.com/image_path/image:tag

If it is daily build for container backup purpose, the tag can be in date format, such as YYYYMMDD. The output can be

20210624: Pulling from image_path/image
...
22b5d63ad977: Already exists
8e2e66517d7e: Pull complete
Digest: sha256:7535af1f65524f9200b901fc31b9c779819e45c0502ef99605666842a319908f

Get Digest by deleting local image

The digest is also printed when deleting it.

docker rmi registry.example.com/image_path/image:tag

Sample output as below

Untagged: registry.example.com/image_path/image:tag
Untagged: registry.example.com/image_path/image@sha256:e300ff463dc18c7b3bf3964dc5a9832f613d829285a0da49e5fd37519dc7d0fc
Deleted: sha256:35baba3d5948b5844b67adcd6a236905039e929f8647d4e4afc9e64e9460d557
Deleted: sha256:bd681f3956f55dc028bae7ca4c2657457824a0e356c59705302fb084660a669b

Note: The Digest is the second tag, the sha256 in the first Deleted message is allowed to be deleted too, but the sha256 in the second Deleted message was not. Don't understand why

Get Digest by curl command

curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET https://$USER:$PASSWORD@registry.example.com/v
2/image_path/image/manifests/tag 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'

Check manifests existence

curl https://$USER:$PASSWORD@registry.example.com/v2/image_path/image/manifests/sha256:xxxxxxxxxxxxxxxx

Delete tag

curl -X DELETE https://$USER:$PASSWORD@registry.example.com/v2/image_path/image/manifests/sha256:xxxxxxxxxxxxxxxx

Run garbage-collect

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

Restart registry if necessary

docker restart registry

Script to delete old docker images

Script to delete old docker images

To schedule a task to delete old docker images.

Assumption

Assuming there is a local copy of image normally. If not, need to directly operate in registry server or pull image locally before execution.

Prereq

Following information should be set as environment variable.

user=username
password=password
registry=registry.example.net
repo=repo

List images

List by image date

This is for local images, list all images' digests created 30 days ago.

docker images $registry/$repo --digests --format "{{.Repository}} {{.Tag}} {{.ID}} {{.Digest}} {{.CreatedAt}}" | awk '{if ($5 < strftime("%Y-%m-%d", systime()-3600*24*30)) {print $1,$2,$3,$4}}'

List by tags

List all tags in format of YYYYDDMM older than 30 days.

TAG_LIST=`curl -s https://$user:$password@$registry/v2/$repo/tags/list | jq '.tags[] | select(. < (now-3600*24*30 | strftime("%Y%m%d")) )'`

Note: strflocaltime can be used if your jq supports it.

Query remote manifest by tag

Using docker command

docker manifest inspect $registry/$repo:$tag -v | jq '.Descriptor.digest'

or using rest api

curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET https://username:password@registry.example.net/v2/${repo}/manifests/20210624 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'

Delete tags

Delete from registry

curl -X DELETE https://$username:$password@$registry/v2/${repo}/manifests/sha256:xxxxxxxxxxxxxxxx

Delete from local

Delete image using image id.

docker rmi $image_id

Script

#!/bin/bash

. ./set_env.sh

user=USERNAME
password=$PASSWORD

repo=${1:-repo_name}
registry=REGISTRY_NAME
keep_days=30

## List all docker images

docker images $registry/$repo --digests --format "{{.Repository}} {{.Tag}} {{.ID}} {{.Digest}} {{.CreatedAt}}" | awk -v keep_days=$keep_days '{if ($5 < strftime("%Y-%m-%d", systime()-3600*24*keep_days)) {print $1,$2,$3,$4}}' | while read line
do
        read repo_path tag id manifest <<< $line

        echo Deleting from registry: $line
        curl -X DELETE https://$user:$password@$registry/v2/${repo}/manifests/$manifest

        echo Deleting from local: $line
        docker rmi $id
done

## List all docker images with tags in registry server
curl -s https://$user:$password@$registry/v2/$repo/tags/list | jq '.tags[] | select(. < (now-3600*24*30 | strftime("%Y%m%d")) )' | tr -d '"' | while read tag
do
        echo Deleting from registry: $tag
        manifest=`docker manifest inspect $registry/$repo:$tag -v | jq '.Descriptor.digest' | tr -d '"'`
        curl -X DELETE https://$user:$password@$registry/v2/${repo}/manifests/$manifest
done

References

Docker Registry HTTP API V2
Can I get an image digest without downloading the image?

Clean up docker registry

Clean up docker registry

After docker containers are backed up daily to docker registry, clean up process is required.

Note: If the image without tag, and if it can be found client locately, then can run command docker inspect to find out. Otherwise, can check "Run command from server" section find out.

List _catalog (repositries)

Following curl command can be used to display all _catalog (repositries).

curl https://username:password@registry.example.net/v2/_catalog

List images (tags) for each repositry

Following curl command can be used to display tags for specific repo

curl https://username:password@registry.example.net/v2/${repo}/tags/list

Get Digest

Using pull request

Use pull image command to get digest as below.

docker pull registry.example.net/${repo}:20210624
20210624: Pulling from user/host/dnsmasq
...
22b5d63ad977: Already exists
8e2e66517d7e: Pull complete
Digest: sha256:7535af1f65524f9200b901fc31b9c779819e45c0502ef99605666842a319908f

Get digest when deleting local image

Using delete local image action also can get digest as well

docker rmi registry.example.net/${repo}:20210619
# Untagged: registry.example.net/user/host/dnsmasq:20210619
# Untagged: registry.example.net/user/host/dnsmasq@sha256:e300ff463dc18c7b3bf3964dc5a9832f613d829285a0da49e5fd37519dc7d0fc
# Deleted: sha256:35baba3d5948b5844b67adcd6a236905039e929f8647d4e4afc9e64e9460d557
# Deleted: sha256:bd681f3956f55dc028bae7ca4c2657457824a0e356c59705302fb084660a669b

The Digest is the second tag.

Note: The first deleted sha256 allowed to be deleted too, but not the second deleted. Don't understand why

Run command from client

Run following command to get Digest

curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET https://username:password@registry.example.net/v2/${repo}/manifests/20210624 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'

Run command from server

This is usefull if there is no image at client and no tag for specfic image.

docker exec privateregistry_registry_1 bin/registry garbage-collect --dry-run /etc/docker/registry/config.yml | grep '${repo}: marking manifest' | awk '{print $4}'

Check manifests exists or not

curl https://username:password@registry.example.net/v2/${repo}/manifests/sha256:xxxxxxxxxxxxxxxx

Delete tag

curl -X DELETE https://username:password@registry.example.net/v2/${repo}/manifests/sha256:xxxxxxxxxxxxxxxx

Delete _catalog

The v2 registry doesn't allow deleting only certain tags from an image, and deletion of tags is in an open PR for a future version of the Registry (https://github.com/docker/distribution/pull/2169).

rm -rf docker/registry/v2/repositories/${repo}/

*Note: After delete, garbage-collect, restart, the repo is still reporting out as empty _catalog.

Run garbage-collect

Login to registry server and run following command

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

If the repo is still listed in the output, need to delete them too.

Restart registry if necessary

docker restart registry

References

Docker Private Registry - Deleted all images, but still showing in catalog
Clean Up Your Docker Registry
Delete repository from v2 private registry
Pull Request - New Tags API #2169
Docker Registry HTTP API V2

Configure trust self generated CA certificate of docker registry

Configure trust self generated CA certificate of docker registry

When self generated CA certificate has not been trusted by docker client, following error occurres

... x509: certificate signed by unknown authority

Install CA certificate for docker only

Docker can install registry CA as /etc/docker/certs.d/<registry[:port]>/ca.crt. For example,

/etc/docker/certs.d/my-registry.example.com:5000/ca.crt

Note: If port is 443, it should be omitted. Otherwise, it won't work.

Install CA certificate into system folder

To install self generated CA certificate for operating system, follow the page below.

Install self generated CA certificate into Linux OS

Restart docker service to take effect

The restart docker service after CA certificate installed.

systemctl restart docker

Backup docker container using shell script

j# Backup docker container using shell script

Backup

Using following shell script to backup docker container with date tag

#!/bin/bash
# backup-docker.sh <container_name> <registry_path>

container=$1            # <container_name>
repo_prefix=$2          # <registry>/<prefix>
registry=${repo_prefix//\/*/}

repo_name=$repo_prefix/`hostname`/$container
repo_path=$repo_name:`date +%Y%m%d`

docker commit $container $repo_path
docker login $registry
docker push $repo_path

Note: If following certification error occurred, follow the page below to install ceritficate.

Configure trust self generated ca certificate of docker registry

List repo

Using following shell command to list repo list in docker registry

curl https://bianxi:$PASSWORD@${registry}/v2/_catalog

Sample output

{"repositories":["bianxi/dnsmasq","bianxi/heart/dnsmasq"]}

List tags

Using follwing shell command to list tags for one repo in docker registry

echo curl https://bianxi:$PASSWORD@${registry}/v2/${repo}/tags/list

Sample output

{"name":"bianxi/heart/dnsmasq","tags":["20210620","20210621","20210622","20210623","20210624","20210625","20210626","20210627"]}

Get digest for tag

Get digest by pull image

docker pull registry.bx.net/bianxi/heart/dnsmasq:20210624

Sample output

20210624: Pulling from bianxi/heart/dnsmasq
...
22b5d63ad977: Already exists
8e2e66517d7e: Pull complete
Digest: sha256:7535af1f65524f9200b901fc31b9c779819e45c0502ef99605666842a319908f

Verify digest

curl https://bianxi:$PASSWORD@registry.bx.net/v2/bianxi/heart/dnsmasq/manifests/sha256:xxxxxxxxxxxxxxxx
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET https://bianxi:$PASSWORD@registry.bx.net/v2/bianxi/heart/dnsmasq/manifests/20210624 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'

Delete local repo

docker rmi registry.bx.net/bianxi/heart/dnsmasq:<tag>

Delete tag

curl -X DELETE https://bianxi:$PASSWORD@registry.bx.net/v2/bianxi/heart/dnsmasq/manifests/sha256:xxxxxxxxxxxxxxxx

Run garbage-collect

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

Restart registry if necessary

docker restart registry

Increase client_max_body_size in NGINX for docker registry

Increase client_max_body_size in NGINX for docker registry

Error "413 Request Entity Too Large" occurred when push image to docker registry.

To fix this issue, add client_max_body_size in NGINX configuration file for docker registry as below, then restart NGINX.

server {
    listen 443;
    server_name hub.bx.net docker.bx.net registry.bx.net dockerhub.bx.net;

    location /v2/ {
        proxy_pass https://registry.my_bridge/v2/;
        proxy_set_header  Authorization $http_authorization;
        proxy_pass_header Authorization;
    }

    client_max_body_size 100M;
}