DEV Community

Łukasz Wolnik
Łukasz Wolnik

Posted on

Reclaiming free disk space from a private Docker repository

My private Docker repository just hit 200 GB in size. Below is an instruction on how to reclaim most of that disk space back by deleting old registry's tags.

First mark tags for deletion based on year. There's a regex that will match all tags from years 2021-2023:

#!/bin/bash

# Docker repository details
REGISTRY="https://docker.foo.com"
REPOSITORY="foo-frontend"
USERNAME="username"
PASSWORD="password"

# Get all tags
tags_json=$(curl -sk -u "$USERNAME:$PASSWORD" "$REGISTRY/v2/$REPOSITORY/tags/list")
tags_to_delete=$(echo "$tags_json" | jq -r '.tags[]' | grep -E '^202[123][0-9]{4}$')

# Delete tags
echo "Deleting tags from 2021 and 2022:"
while IFS= read -r tag; do
    echo "Deleting tag: $tag"
    ./delete-tag.sh "$tag" "$REPOSITORY"
    echo "Tag $tag deletion process completed."
done <<< "$tags_to_delete"

echo "All deletion processes completed."
Enter fullscreen mode Exit fullscreen mode

Now the script delete-tag.sh that gets digest for a given tag and marks it for deletion:

#!/bin/bash

if [ $# -eq 0 ]; then
    echo "Error: Please provide a TAG value as an argument."
    exit 1
fi

# Set your registry URL, repository name, and credentials
REGISTRY_URL="https://docker.foo.com"
REPO_NAME="$2"
TAG="$1"
USERNAME="username"
PASSWORD="password"

echo "Received TAG: $TAG"

echo "Fetching manifest for ${REPO_NAME}:${TAG}"
MANIFEST=$(curl -s -k -u "${USERNAME}:${PASSWORD}" \
  -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
  "${REGISTRY_URL}/v2/${REPO_NAME}/manifests/${TAG}")

echo "Debug - Manifest output:"
#echo "$MANIFEST"

if [[ $MANIFEST == *"errors"* ]]; then
  echo "Error fetching manifest:"
  echo "$MANIFEST" | jq .
else
  echo "Manifest found. Extracting digest..."
  CURL_OUTPUT=$(curl -s -k -u "${USERNAME}:${PASSWORD}" \
    -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
    -I "${REGISTRY_URL}/v2/${REPO_NAME}/manifests/${TAG}")

  echo "Debug - Curl output for digest:"
#  echo "$CURL_OUTPUT"

  DIGEST=$(echo "$CURL_OUTPUT" | grep -i Docker-Content-Digest | awk '{print $2}' | tr -d '\r\n')

  echo "Digest: ${DIGEST}"
  echo "Attempting to delete..."

  DELETE_RESPONSE=$(curl -s -i -k -u "${USERNAME}:${PASSWORD}" \
    -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
    -X DELETE "${REGISTRY_URL}/v2/${REPO_NAME}/manifests/${DIGEST}")

  echo "Delete response:"
#  echo "$DELETE_RESPONSE"

  if [[ $DELETE_RESPONSE == *"202"* ]]; then
    echo "Tag deleted successfully."
  else
    echo "Failed to delete tag. Check the response for more details."
  fi
fi

echo "Script execution completed."
Enter fullscreen mode Exit fullscreen mode

Lastly run docker ps to identify registry:2 container id and run:

docker exec <container_id> bin/registry garbage-collect /etc/docker/registry/config.yml
Enter fullscreen mode Exit fullscreen mode

Run below to confirm there's now more free space on your disk:

df -h
Enter fullscreen mode Exit fullscreen mode

Getting all repos from a Docker Registry

curl -k -u username:password -X GET https://docker.foo.com/v2/_catalog
Enter fullscreen mode Exit fullscreen mode

Getting all tags for a given regsitry

curl -k -u username:password -X GET http://docker.foo.com/v2/bar/tags/list
Enter fullscreen mode Exit fullscreen mode

Top comments (0)