Last active
July 1, 2025 16:16
-
-
Save fabiobarboza7/5c1442e0ed0faacd0ebd382249d61923 to your computer and use it in GitHub Desktop.
Docker Full Cleanup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# My old version now LLM refactored... added some fancy logs... | |
# Enhanced Docker Cleanup Script | |
# This script provides comprehensive Docker environment cleanup with safety features | |
# Author: Enhanced version with additional cleanup targets and features | |
# Define style variables with color detection | |
if [[ -t 1 ]] && [[ "${TERM:-}" != "dumb" ]] && command -v /usr/bin/tput >/dev/null 2>&1 && /usr/bin/tput colors >/dev/null 2>&1 && [[ $(/usr/bin/tput colors) -ge 8 ]]; then | |
RED='\033[0;31m' | |
GREEN='\033[0;32m' | |
YELLOW='\033[1;33m' | |
BLUE='\033[0;34m' | |
CYAN='\033[0;36m' | |
BOLD='\033[1m' | |
NC='\033[0m' # No Color | |
else | |
# No color support - use empty strings | |
RED='' | |
GREEN='' | |
YELLOW='' | |
BLUE='' | |
CYAN='' | |
BOLD='' | |
NC='' | |
fi | |
# Script configuration | |
SCRIPT_VERSION="2.0" | |
DRY_RUN=false | |
VERBOSE=false | |
FORCE_MODE=false | |
# Function to print colored output | |
print_info() { echo -e "${BLUE}ℹ ${NC} $1"; } | |
print_success() { echo -e "${GREEN}✓${NC} $1"; } | |
print_warning() { echo -e "${YELLOW}⚠${NC} $1"; } | |
print_error() { echo -e "${RED}✗${NC} $1"; } | |
print_header() { echo -e "\n${BOLD}${CYAN}=== $1 ===${NC}"; } | |
# Function to check if Docker is running | |
check_docker() { | |
if ! docker info >/dev/null 2>&1; then | |
print_error "Docker is not running or not installed." | |
exit 1 | |
fi | |
} | |
# Function to get Docker disk usage before cleanup | |
get_disk_usage() { | |
docker system df 2>/dev/null || echo "Unable to get disk usage" | |
} | |
# Function to execute commands with dry-run support | |
execute_cmd() { | |
local cmd="$1" | |
local description="$2" | |
if [ "$DRY_RUN" = true ]; then | |
print_info "[DRY RUN] Would execute: $cmd" | |
else | |
if [ "$VERBOSE" = true ]; then | |
print_info "Executing: $cmd" | |
fi | |
eval "$cmd" 2>/dev/null | |
local status=$? | |
if [ $status -eq 0 ]; then | |
[ -n "$description" ] && print_success "$description" | |
else | |
[ -n "$description" ] && print_warning "$description (may have already been cleaned)" | |
fi | |
return $status | |
fi | |
} | |
# Function to stop and remove all containers | |
cleanup_containers() { | |
print_header "Cleaning up containers" | |
# Stop all running containers | |
local running=$(docker container ls -q 2>/dev/null) | |
if [ -n "$running" ]; then | |
execute_cmd "docker container stop $running" "Stopped running containers" | |
else | |
print_info "No running containers to stop" | |
fi | |
# Remove all containers | |
local containers=$(docker container ls -aq 2>/dev/null) | |
if [ -n "$containers" ]; then | |
execute_cmd "docker container rm -f $containers" "Removed all containers" | |
else | |
print_info "No containers to remove" | |
fi | |
} | |
# Function to remove all images | |
cleanup_images() { | |
print_header "Cleaning up images" | |
local images=$(docker image ls -aq 2>/dev/null) | |
if [ -n "$images" ]; then | |
execute_cmd "docker image rm -f $images" "Removed all images" | |
else | |
print_info "No images to remove" | |
fi | |
} | |
# Function to remove all volumes | |
cleanup_volumes() { | |
print_header "Cleaning up volumes" | |
local volumes=$(docker volume ls -q 2>/dev/null) | |
if [ -n "$volumes" ]; then | |
execute_cmd "docker volume rm -f $volumes" "Removed all volumes" | |
else | |
print_info "No volumes to remove" | |
fi | |
} | |
# Function to remove custom networks | |
cleanup_networks() { | |
print_header "Cleaning up networks" | |
# Get all networks except the predefined ones | |
local networks=$(docker network ls --filter "type=custom" --format '{{.Name}}' 2>/dev/null) | |
if [ -n "$networks" ]; then | |
for network in $networks; do | |
execute_cmd "docker network rm \"$network\"" "Removed network: $network" | |
done | |
else | |
print_info "No custom networks to remove" | |
fi | |
} | |
# Function to cleanup Docker Swarm resources | |
cleanup_swarm() { | |
print_header "Cleaning up Docker Swarm resources" | |
# Check if node is part of a swarm | |
if docker info 2>/dev/null | /usr/bin/grep -q "Swarm: active"; then | |
# Remove services | |
local services=$(docker service ls -q 2>/dev/null) | |
if [ -n "$services" ]; then | |
execute_cmd "docker service rm $services" "Removed all services" | |
fi | |
# Remove secrets | |
local secrets=$(docker secret ls -q 2>/dev/null) | |
if [ -n "$secrets" ]; then | |
execute_cmd "docker secret rm $secrets" "Removed all secrets" | |
fi | |
# Remove configs | |
local configs=$(docker config ls -q 2>/dev/null) | |
if [ -n "$configs" ]; then | |
execute_cmd "docker config rm $configs" "Removed all configs" | |
fi | |
# Leave swarm | |
execute_cmd "docker swarm leave --force" "Left Docker Swarm" | |
else | |
print_info "Not part of a Docker Swarm" | |
fi | |
} | |
# Function to cleanup build cache and builders | |
cleanup_build_cache() { | |
print_header "Cleaning up build cache and builders" | |
# Prune build cache | |
execute_cmd "docker builder prune -a -f" "Pruned all build cache" | |
# Remove buildx builders (if buildx is available) | |
if docker buildx version >/dev/null 2>&1; then | |
local builders=$(docker buildx ls | /usr/bin/grep -v "default\\|docker" | /usr/bin/awk 'NR>1 {print $1}' | /usr/bin/grep -v "^NAME$" 2>/dev/null) | |
if [ -n "$builders" ]; then | |
for builder in $builders; do | |
execute_cmd "docker buildx rm $builder" "Removed buildx builder: $builder" | |
done | |
fi | |
fi | |
} | |
# Function to cleanup Docker contexts | |
cleanup_contexts() { | |
print_header "Cleaning up Docker contexts" | |
# Get all contexts except default | |
local contexts=$(docker context ls --format '{{.Name}}' | /usr/bin/grep -v "^default$" 2>/dev/null) | |
if [ -n "$contexts" ]; then | |
for context in $contexts; do | |
execute_cmd "docker context rm -f \"$context\"" "Removed context: $context" | |
done | |
else | |
print_info "No custom contexts to remove" | |
fi | |
} | |
# Function to cleanup Docker plugins | |
cleanup_plugins() { | |
print_header "Cleaning up Docker plugins" | |
local plugins=$(docker plugin ls -q 2>/dev/null) | |
if [ -n "$plugins" ]; then | |
for plugin in $plugins; do | |
execute_cmd "docker plugin disable $plugin" "" | |
execute_cmd "docker plugin rm -f $plugin" "Removed plugin" | |
done | |
else | |
print_info "No plugins to remove" | |
fi | |
} | |
# Function to perform system-wide prune | |
system_prune() { | |
print_header "Performing system-wide cleanup" | |
execute_cmd "docker system prune -a -f --volumes" "System prune completed" | |
} | |
# Function to show help | |
show_help() { | |
printf "${BOLD}${CYAN}Docker Cleanup Script v${SCRIPT_VERSION}${NC}\n" | |
printf "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n\n" | |
printf "${BOLD}USAGE:${NC}\n" | |
printf " %s [OPTIONS]\n\n" "$0" | |
printf "${BOLD}OPTIONS:${NC}\n" | |
printf " ${GREEN}-h, --help${NC} Show this help message and exit\n" | |
printf " ${GREEN}-d, --dry-run${NC} Preview what would be deleted without actually deleting\n" | |
printf " ${GREEN}-v, --verbose${NC} Show detailed output of each command being executed\n" | |
printf " ${GREEN}-f, --force${NC} Skip confirmation prompt (use with caution!)\n" | |
printf " ${GREEN}-V, --version${NC} Show script version and exit\n\n" | |
printf "${BOLD}DESCRIPTION:${NC}\n" | |
printf " This script performs a comprehensive cleanup of your Docker environment.\n" | |
printf " It systematically removes all Docker resources in the following order:\n\n" | |
printf "${BOLD}CLEANUP OPERATIONS:${NC}\n" | |
printf " ${CYAN}1. Containers${NC}\n" | |
printf " • Stops all running containers\n" | |
printf " • Removes all containers (running and stopped)\n\n" | |
printf " ${CYAN}2. Images${NC}\n" | |
printf " • Removes all Docker images (including intermediate layers)\n\n" | |
printf " ${CYAN}3. Volumes${NC}\n" | |
printf " • Removes all Docker volumes (persistent data storage)\n\n" | |
printf " ${CYAN}4. Networks${NC}\n" | |
printf " • Removes all custom networks (keeps default bridge, host, none)\n\n" | |
printf " ${CYAN}5. Swarm Resources${NC} (if applicable)\n" | |
printf " • Removes all services, secrets, and configs\n" | |
printf " • Forces the node to leave the swarm\n\n" | |
printf " ${CYAN}6. Build Cache${NC}\n" | |
printf " • Removes all build cache\n" | |
printf " • Removes buildx builders (if buildx is installed)\n\n" | |
printf " ${CYAN}7. Contexts${NC}\n" | |
printf " • Removes all custom Docker contexts (keeps default)\n\n" | |
printf " ${CYAN}8. Plugins${NC}\n" | |
printf " • Disables and removes all Docker plugins\n\n" | |
printf " ${CYAN}9. System Prune${NC}\n" | |
printf " • Performs final system-wide cleanup\n\n" | |
printf "${BOLD}EXAMPLES:${NC}\n" | |
printf " ${BLUE}# Preview what will be deleted:${NC}\n" | |
printf " %s --dry-run\n\n" "$0" | |
printf " ${BLUE}# Run cleanup with detailed output:${NC}\n" | |
printf " %s --verbose\n\n" "$0" | |
printf " ${BLUE}# Force cleanup without confirmation:${NC}\n" | |
printf " %s --force\n\n" "$0" | |
printf " ${BLUE}# Combine options:${NC}\n" | |
printf " %s -d -v # Dry run with verbose output\n\n" "$0" | |
printf "${BOLD}${RED}⚠️ WARNING:${NC}\n" | |
printf " This script will ${RED}PERMANENTLY DELETE${NC} all Docker resources!\n" | |
printf " • All container data will be lost\n" | |
printf " • All volumes and their data will be deleted\n" | |
printf " • All downloaded images will be removed\n\n" | |
printf " ${YELLOW}Make sure to backup any important data before proceeding!${NC}\n\n" | |
printf "${BOLD}REQUIREMENTS:${NC}\n" | |
printf " • Docker must be installed and running\n" | |
printf " • Sufficient permissions to execute Docker commands\n\n" | |
printf "${BOLD}AUTHOR:${NC}\n" | |
printf " Enhanced Docker Cleanup Script v${SCRIPT_VERSION}\n\n" | |
} | |
# Parse command line arguments | |
while [[ $# -gt 0 ]]; do | |
case $1 in | |
-h|--help) | |
show_help | |
exit 0 | |
;; | |
-d|--dry-run) | |
DRY_RUN=true | |
shift | |
;; | |
-v|--verbose) | |
VERBOSE=true | |
shift | |
;; | |
-f|--force) | |
FORCE_MODE=true | |
shift | |
;; | |
-V|--version) | |
echo "Docker Cleanup Script v${SCRIPT_VERSION}" | |
exit 0 | |
;; | |
*) | |
print_error "Unknown option: $1" | |
show_help | |
exit 1 | |
;; | |
esac | |
done | |
# Main execution | |
# Clear screen if available, otherwise just add some spacing | |
if command -v /usr/bin/clear >/dev/null 2>&1; then | |
/usr/bin/clear | |
else | |
echo -e "\n\n" | |
fi | |
echo -e "${BOLD}${CYAN}Docker Cleanup Script v${SCRIPT_VERSION}${NC}" | |
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" | |
# Check if Docker is running | |
check_docker | |
# Show current disk usage | |
print_header "Current Docker disk usage" | |
get_disk_usage | |
if [ "$DRY_RUN" = true ]; then | |
print_warning "Running in DRY RUN mode - no changes will be made" | |
fi | |
# Confirmation prompt (unless in force mode) | |
if [ "$FORCE_MODE" != true ] && [ "$DRY_RUN" != true ]; then | |
echo | |
print_warning "This will remove ALL Docker resources including:" | |
echo " • All containers (running and stopped)" | |
echo " • All images" | |
echo " • All volumes" | |
echo " • All custom networks" | |
echo " • All build cache" | |
echo " • All Swarm resources (if applicable)" | |
echo " • All custom contexts" | |
echo " • All plugins" | |
echo | |
read -p "$(echo -e ${YELLOW}Are you sure you want to continue? [y/N]:${NC} )" response | |
if [[ ! "$response" =~ ^[Yy]$ ]]; then | |
print_info "Cleanup cancelled" | |
exit 0 | |
fi | |
fi | |
# Record start time | |
start_time=$(/bin/date +%s) | |
# Ensure Docker binary path is available | |
export PATH=$PATH:/usr/local/bin | |
# Execute cleanup operations | |
cleanup_containers | |
cleanup_images | |
cleanup_volumes | |
cleanup_networks | |
cleanup_swarm | |
cleanup_build_cache | |
cleanup_contexts | |
cleanup_plugins | |
system_prune | |
# Show final disk usage | |
if [ "$DRY_RUN" != true ]; then | |
print_header "Final Docker disk usage" | |
get_disk_usage | |
fi | |
# Calculate execution time | |
end_time=$(/bin/date +%s) | |
execution_time=$((end_time - start_time)) | |
echo | |
print_success "Docker cleanup completed in ${execution_time} seconds!" | |
if [ "$DRY_RUN" = true ]; then | |
print_info "This was a dry run. No changes were made." | |
print_info "Run without -d/--dry-run to actually perform the cleanup." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Examples: