#!/bin/bash # Script: docker-cleanup.sh # Description: Cleans up unused Docker images, volumes, networks, and builder cache. # Preserves stopped containers. # Calculates reclaimed space and logs it to syslog. # Dependencies: docker, bc, grep (with PCRE support) USAGE_TAG="docker-cleanup" # Logging functions log_info() { logger -t "$USAGE_TAG" -p user.info "$1" } log_error() { logger -t "$USAGE_TAG" -p user.error "$1" } # Check for 'bc' dependency if ! command -v bc &> /dev/null; then log_error "Error: 'bc' is not installed. Please install it (apt install bc) to calculate reclaimed space." # Fail safe: don't run blindly if we can't calculate/log properly, or just run without logging space? # User requested logging to syslog, assuming they want the space report. exit 1 fi log_info "Starting Docker cleanup (Images, Volumes, Networks, Builder)..." # Initialize output variable OUTPUT="" # 1. Prune Images (all unused images, not just dangling) with input 'y' just in case, though -f usually covers it # Note: 'image prune -a' removes images not used by ANY container (including stopped ones). CMD_OUTPUT=$(docker image prune -a -f 2>&1) OUTPUT="${OUTPUT}${CMD_OUTPUT}"$'\n' # 2. Prune Volumes CMD_OUTPUT=$(docker volume prune -f 2>&1) OUTPUT="${OUTPUT}${CMD_OUTPUT}"$'\n' # 3. Prune Networks CMD_OUTPUT=$(docker network prune -f 2>&1) OUTPUT="${OUTPUT}${CMD_OUTPUT}"$'\n' # 4. Prune Builder Cache CMD_OUTPUT=$(docker builder prune -f 2>&1) OUTPUT="${OUTPUT}${CMD_OUTPUT}"$'\n' # Check for critical failures (though docker commands might succeed partially) # We proceed to calculate space regardless. # Extract reclaimed space amounts using grep with Perl-compatible regex. RECLAIMED_SPACES=$(echo "$OUTPUT" | grep -Po '(?<=Total reclaimed space: )[0-9.]+[A-Z]+' | grep -v '^0B$') # Initialize total reclaimed space counter TOTAL_RECLAIMED=0 # Loop through each reclaimed space value for SPACE in $RECLAIMED_SPACES; do # Extract the unit (KB, MB, GB) UNIT=${SPACE: -2} # Extract the numeric value VALUE=${SPACE%${UNIT}} # Normalize to GB case $UNIT in kB|KB) VAL_IN_GB=$(echo "$VALUE / 1024 / 1024" | bc -l) ;; mB|MB) VAL_IN_GB=$(echo "$VALUE / 1024" | bc -l) ;; gB|GB) VAL_IN_GB=$VALUE ;; *) VAL_IN_GB=0 ;; esac # Add to total TOTAL_RECLAIMED=$(echo "$TOTAL_RECLAIMED + $VAL_IN_GB" | bc -l) done # Check if we reclaimed anything significant (greater than 0) IS_POSITIVE=$(echo "$TOTAL_RECLAIMED > 0" | bc -l) if [ "$IS_POSITIVE" -eq 1 ]; then # Format to 3 decimal places FORMATTED_TOTAL=$(printf "%.3f" "$TOTAL_RECLAIMED") log_info "Cleanup finished. Total reclaimed space: ${FORMATTED_TOTAL} GB" else log_info "Cleanup finished. No significant space was reclaimed." fi exit 0