Skip to content

Instantly share code, notes, and snippets.

@rkalkani
Last active July 15, 2025 10:44
Show Gist options
  • Select an option

  • Save rkalkani/868012e53676f1c95a4defddaa8f30f4 to your computer and use it in GitHub Desktop.

Select an option

Save rkalkani/868012e53676f1c95a4defddaa8f30f4 to your computer and use it in GitHub Desktop.
A bash script to efficiently manage Docker images by automatically cleaning up old and unused images while maintaining the most recent versions. The script helps prevent disk space issues by intelligently managing Docker resources.
#!/bin/bash
# Helper Comments:
# This script helps manage Docker images by cleaning up old and unused images
# while keeping a specified number of recent images per repository.
#
# Usage:
# ./clean-docker-images.sh [--keep N] [--prune-containers] [--prune-dangling]
#
# Parameters:
# --keep N : Keep N most recent images per repository (default: 3)
# --prune-containers : Remove all stopped containers
# --prune-dangling : Remove dangling images (untagged images)
#
# Examples:
# ./clean-docker-images.sh # Keep 3 latest images per repo
# ./clean-docker-images.sh --keep 5 # Keep 5 latest images per repo
# ./clean-docker-images.sh --prune-containers # Also remove stopped containers
# ./clean-docker-images.sh --prune-dangling # Also remove dangling images
#
# Note: This script requires Docker to be installed and running.
# You may need sudo/root privileges depending on Docker setup.
# Default values
KEEP=3
PRUNE_CONTAINERS=false
PRUNE_DANGLING=false
# Parse command-line arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--keep)
KEEP="$2"
shift 2
;;
--prune-containers)
PRUNE_CONTAINERS=true
shift
;;
--prune-dangling)
PRUNE_DANGLING=true
shift
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--keep <number>] [--prune-containers] [--prune-dangling]"
exit 1
;;
esac
done
# Delete dead containers
if [ "$PRUNE_CONTAINERS" = true ]; then
echo "Pruning dead containers..."
docker container prune -f
fi
echo "Cleaning up old images, keeping the last $KEEP per repository..."
# Get list of unique repositories
repos=$(docker images --format "{{.Repository}}" | grep -v "<none>" | sort | uniq)
for repo in $repos; do
# List all images for the repo with tag and ID
mapfile -t images < <(docker images --format "{{.Repository}}:{{.Tag}} {{.ID}}" --filter=reference="$repo")
# Build array with image tag and creation time
image_data=()
for img in "${images[@]}"; do
tag=$(echo "$img" | awk '{print $1}')
id=$(echo "$img" | awk '{print $2}')
created=$(docker image inspect "$id" --format '{{.Created}}')
created_epoch=$(date -d "$created" +%s)
image_data+=("$created_epoch;$tag;$id")
done
# Sort by creation date descending
sorted=($(printf "%s\n" "${image_data[@]}" | sort -t';' -k1 -nr))
# Remove images beyond KEEP limit
for ((i=KEEP; i<${#sorted[@]}; i++)); do
line="${sorted[$i]}"
tag=$(echo "$line" | cut -d';' -f2)
echo "Removing image: $tag"
docker rmi "$tag"
echo ""
done
done
# Clean dangling images
if [ "$PRUNE_DANGLING" = true ]; then
echo "Pruning dangling images..."
docker image prune -f
fi
echo "Cleanup complete."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment