63c12a2f44
eula support * eula support * docs
112 lines
3.1 KiB
Bash
Executable File
112 lines
3.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# cleanup.docker.images.sh
|
|
#
|
|
# Removes old Docker images, keeping only the newest image per repository.
|
|
# Images are sorted by creation date, and only the most recent per repo is retained.
|
|
#
|
|
# Usage:
|
|
# ./cleanup.docker.images.sh [--dryrun]
|
|
#
|
|
# Options:
|
|
# --dryrun Show what would be deleted without actually deleting
|
|
#
|
|
# Returns:
|
|
# 0 on success
|
|
# 1 on error
|
|
|
|
set -euo pipefail
|
|
|
|
DRYRUN=false
|
|
|
|
# Parse arguments
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
--dryrun)
|
|
DRYRUN=true
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
echo "Usage: $0 [--dryrun]"
|
|
echo ""
|
|
echo "Removes old Docker images, keeping only the newest per repository."
|
|
echo ""
|
|
echo "Options:"
|
|
echo " --dryrun Show what would be deleted without actually deleting"
|
|
echo " --help Show this help message"
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $arg"
|
|
echo "Use --help for usage information"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Get images to delete: all but the newest per repository
|
|
# Format: repository|tag|id|created
|
|
# Sort by repo, then by date descending (newest first)
|
|
# Skip the first (newest) for each repo, output the rest
|
|
get_images_to_delete() {
|
|
docker images --format '{{.Repository}}|{{.Tag}}|{{.ID}}|{{.CreatedAt}}' | \
|
|
grep -v '<none>' | \
|
|
sort -t'|' -k1,1 -k4r | \
|
|
awk -F'|' 'seen[$1]++ {print $1"|"$2"|"$3}'
|
|
}
|
|
|
|
# Get unique image IDs from the list
|
|
get_unique_ids() {
|
|
awk -F'|' '{print $3}' | sort -u
|
|
}
|
|
|
|
echo "Scanning Docker images..."
|
|
echo ""
|
|
|
|
IMAGES_TO_DELETE=$(get_images_to_delete)
|
|
|
|
if [ -z "$IMAGES_TO_DELETE" ]; then
|
|
echo "No old images to clean up. Each repository has only one image."
|
|
exit 0
|
|
fi
|
|
|
|
# Count images
|
|
IMAGE_COUNT=$(echo "$IMAGES_TO_DELETE" | wc -l | tr -d ' ')
|
|
UNIQUE_IDS=$(echo "$IMAGES_TO_DELETE" | get_unique_ids)
|
|
UNIQUE_COUNT=$(echo "$UNIQUE_IDS" | wc -l | tr -d ' ')
|
|
|
|
if [ "$DRYRUN" = true ]; then
|
|
echo "=== DRY RUN MODE ==="
|
|
echo "The following images would be deleted ($IMAGE_COUNT tags, $UNIQUE_COUNT unique images):"
|
|
echo ""
|
|
printf "%-50s %-35s %s\n" "REPOSITORY" "TAG" "IMAGE ID"
|
|
printf "%-50s %-35s %s\n" "----------" "---" "--------"
|
|
echo "$IMAGES_TO_DELETE" | while IFS='|' read -r repo tag id; do
|
|
printf "%-50s %-35s %s\n" "$repo" "$tag" "$id"
|
|
done
|
|
echo ""
|
|
echo "Run without --dryrun to delete these images."
|
|
else
|
|
echo "Deleting $IMAGE_COUNT image tags ($UNIQUE_COUNT unique images)..."
|
|
echo ""
|
|
|
|
DELETED=0
|
|
FAILED=0
|
|
|
|
for id in $UNIQUE_IDS; do
|
|
if docker rmi "$id" 2>/dev/null; then
|
|
((DELETED++)) || true
|
|
else
|
|
# Try force removal if normal removal fails
|
|
if docker rmi -f "$id" 2>/dev/null; then
|
|
((DELETED++)) || true
|
|
else
|
|
echo "Warning: Could not delete image $id (may be in use)"
|
|
((FAILED++)) || true
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "Cleanup complete: $DELETED deleted, $FAILED failed/skipped"
|
|
fi
|