#!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail LOG_FILE="/var/log/ailab-docker-cleanup.log" execute=false non_interactive=false usage() { printf 'Usage: %s [--execute [--non-interactive]]\n' "$(basename "$0")" } while (($# > 0)); do case "$1" in --execute) execute=true ;; --non-interactive) non_interactive=true ;; -h|--help) usage; exit 0 ;; *) printf 'CRITICAL: unknown argument: %s\n' "$1" >&2; usage >&2; exit 2 ;; esac shift done if [[ "$non_interactive" == true && "$execute" != true ]]; then printf 'CRITICAL: --non-interactive requires --execute\n' >&2 exit 2 fi if ((EUID != 0)); then printf 'CRITICAL: this script must run as root\n' >&2 exit 2 fi exec > >(tee -a "$LOG_FILE") 2>&1 printf '\n[%s] Docker cleanup\n' "$(date --iso-8601=seconds)" if ! command -v docker >/dev/null 2>&1; then printf 'INFO: Docker is not installed; nothing to do\n' exit 0 fi if command -v systemctl >/dev/null 2>&1 && ! systemctl is-active --quiet docker; then printf 'INFO: docker.service is inactive; nothing to do\n' exit 0 fi printf '\nDocker disk usage before cleanup:\n' docker system df if [[ "$execute" != true ]]; then printf 'INFO: dry-run mode; would run docker system prune -af\n' printf 'INFO: dry-run mode; would run docker builder prune -af --filter until=168h\n' printf 'INFO: Docker volumes are never included in this cleanup\n' exit 0 fi if [[ "$non_interactive" != true ]]; then printf 'WARNING: this removes unused containers, networks, images, and old build cache, but not volumes.\n' printf 'Type EXECUTE to continue: ' read -r confirmation if [[ "$confirmation" != "EXECUTE" ]]; then printf 'CRITICAL: confirmation failed; no changes made\n' exit 2 fi fi docker system prune -af docker builder prune -af --filter "until=168h" printf '\nDocker disk usage after cleanup:\n' docker system df printf 'OK: Docker cleanup completed; volumes were not pruned\n'