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?