diff --git a/README.md b/README.md index e2f96fc..97af3d5 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,37 @@ Dieses Script überprüft mehrere Docker-Compose-Stacks auf Image-Updates und ak ## ⚙️ Konfiguration (`config.conf`) ```bash +# ============================= +# ============================= +# Pfade +# ============================= + # Pfad zu deinen Compose-Files COMPOSE_DIR="/pfad/zu/deinen/stacks" +# Logging +LOG_FILE="/pfad/zum/log/update.log" +LOG_LEVEL="INFO" # DEBUG=sehr detailliert, INFO=Standard, WARN=nur wichtige Hinweise/Updates, ERROR=nur Fehler + # Dateimuster COMPOSE_PATTERN="docker-compose.yml" +# ============================= +# ============================= +# Allgemein Einstellungen +# ============================= + +# Verhalten bei gestoppten Containern +UPDATE_STOPPED=true # Image aktualisieren +START_STOPPED=false # danach NICHT starten + +# Dry Run (true/false) +DRY_RUN=false + +# ============================= +# ============================= +# Exclude +# ============================= + # Exclude Container EXCLUDE_SERVICES=( "example_container_1" @@ -39,26 +65,49 @@ EXCLUDE_STACKS=( "example_stack_2" ) -# Verhalten bei gestoppten Containern -UPDATE_STOPPED=true # Image aktualisieren -START_STOPPED=false # danach NICHT starten - -# Dry Run (true/false) -DRY_RUN=false - -# Logging -LOG_FILE="/pfad/zum/log/update.log" -LOG_LEVEL="INFO" - -# ntfy +# ============================= +# ============================= +# NTFY +# ============================= NTFY_ENABLED=true -NTFY_TITLE="Docker Update ($(hostname))" +NTFY_TITLE="Docker Update ($(hostname))" # ntfy Titel (frei definierbar) NTFY_TOKEN="DEIN_TOKEN" NTFY_URL="https://ntfy.example.com/topic" NTFY_TAGS="docker,update" NTFY_ONLY_ON_CHANGES=false -# Versions Nr. der Container in der NTFY Nachricht anzeigen (true/false) +# Versions Nr. anzeigen (true/false) SHOW_VERSIONS=true + +# ============================= +# ============================= +# Docker Cleanup +# ============================= + +ENABLE_CLEANUP=true +CLEANUP_ONLY_ON_UPDATE=true + +# Images: +# 🟢 dangling → docker image prune (nur Images) +# 🟢 unused → docker image prune -a (alle ungenutzten Images) +CLEANUP_IMAGES=true +CLEANUP_IMAGES_MODE="unused" # dangling | unused + +# Container: +# entfernt gestoppte Container +# 🟢 docker container prune +CLEANUP_CONTAINERS=true + +# Volume: +# entfernt ungenutzte Volumes +# ⚠️ kann Daten löschen +CLEANUP_VOLUMES=false + +# Networks: +# entfernt ungenutzte Netzwerke +# 🟢 meist unkritisch +CLEANUP_NETWORKS=true + +# ============================= ``` --- diff --git a/config.conf b/config.conf index 53859c4..8969b5f 100644 --- a/config.conf +++ b/config.conf @@ -1,9 +1,34 @@ +# ============================= +# ============================= +# Pfade +# ============================= + # Pfad zu deinen Compose-Files COMPOSE_DIR="/pfad/zu/deinen/stacks" +# Logging +LOG_FILE="/pfad/zum/log/update.log" +LOG_LEVEL="INFO" # DEBUG=sehr detailliert, INFO=Standard, WARN=nur wichtige Hinweise/Updates, ERROR=nur Fehler # Dateimuster COMPOSE_PATTERN="docker-compose.yml" +# ============================= +# ============================= +# Allgemein Einstellungen +# ============================= + +# Verhalten bei gestoppten Containern +UPDATE_STOPPED=true # Image aktualisieren +START_STOPPED=false # danach NICHT starten + +# Dry Run (true/false) +DRY_RUN=false + +# ============================= +# ============================= +# Exclude +# ============================= + # Exclude Container EXCLUDE_SERVICES=( "example_container_1" @@ -16,18 +41,10 @@ EXCLUDE_STACKS=( "example_stack_2" ) -# Verhalten bei gestoppten Containern -UPDATE_STOPPED=true # Image aktualisieren -START_STOPPED=false # danach NICHT starten - -# Dry Run (true/false) -DRY_RUN=false - -# Logging -LOG_FILE="/pfad/zum/log/update.log" -LOG_LEVEL="INFO" # DEBUG=sehr detailliert, INFO=Standard, WARN=nur wichtige Hinweise/Updates, ERROR=nur Fehler - -# ntfy +# ============================= +# ============================= +# NTFY +# ============================= NTFY_ENABLED=true NTFY_TITLE="Docker Update ($(hostname))" # ntfy Titel (frei definierbar) NTFY_TOKEN="DEIN_TOKEN" @@ -37,5 +54,33 @@ NTFY_ONLY_ON_CHANGES=false # Versions Nr. anzeigen (true/false) SHOW_VERSIONS=true +# ============================= +# ============================= +# Docker Cleanup +# ============================= +ENABLE_CLEANUP=true +CLEANUP_ONLY_ON_UPDATE=true +# Images: +# 🟢 dangling → docker image prune (nur Images) +# 🟢 unused → docker image prune -a (alle ungenutzten Images) +CLEANUP_IMAGES=true +CLEANUP_IMAGES_MODE="unused" # dangling | unused + +# Container: +# entfernt gestoppte Container +# 🟢 docker container prune +CLEANUP_CONTAINERS=true + +# Volume: +# entfernt ungenutzte Volumes +# ⚠️ kann Daten löschen +CLEANUP_VOLUMES=false + +# Networks: +# entfernt ungenutzte Netzwerke +# 🟢 meist unkritisch +CLEANUP_NETWORKS=true + +# ============================= \ No newline at end of file diff --git a/shell_docker_compose_update.sh b/shell_docker_compose_update.sh index 7aa26a2..fe204c8 100644 --- a/shell_docker_compose_update.sh +++ b/shell_docker_compose_update.sh @@ -130,6 +130,27 @@ send_ntfy() { "$NTFY_URL" > /dev/null || true } +get_docker_disk_usage() { + local total=0 + + while read -r size; do + num="${size//[!0-9.]/}" + num="${num:-0}" + + if [[ "$size" == *GB ]]; then + total=$(bc <<< "$total + ($num * 1024)") + elif [[ "$size" == *MB ]]; then + total=$(bc <<< "$total + $num") + elif [[ "$size" == *kB ]]; then + total=$(bc <<< "$total + ($num / 1024)") + fi + done < <(docker system df --format '{{.Size}}' 2>/dev/null) + + log DEBUG "Docker usage raw: $total MB" + + printf "%.0f\n" "$total" +} + # ============================= # Start # ============================= @@ -278,6 +299,60 @@ while IFS= read -r -d '' file; do done < <(find . -name "$COMPOSE_PATTERN" -print0 | sort -z) + +# ============================= +# Cleanup (mit Statistik) +# ============================= + +freed_space="0" + +if [ "$ENABLE_CLEANUP" = true ]; then + + if [ "$CLEANUP_ONLY_ON_UPDATE" = true ] && \ + [ ${#notify_stacks_updated[@]} -eq 0 ]; then + log INFO "🧹 Cleanup übersprungen (keine Updates)" + else + + before_size=$(get_docker_disk_usage) + + log INFO "🧹 Docker Cleanup läuft..." + + if [ "$CLEANUP_IMAGES" = true ]; then + case "$CLEANUP_IMAGES_MODE" in + unused) + log INFO " → Entferne ungenutzte Images" + run_cmd docker image prune -a -f >/dev/null 2>&1 + ;; + dangling) + log INFO " → Entferne dangling Images" + run_cmd docker image prune -f >/dev/null 2>&1 + ;; + esac + fi + + if [ "$CLEANUP_CONTAINERS" = true ]; then + log INFO " → Entferne gestoppte Container" + run_cmd docker container prune -f >/dev/null 2>&1 + fi + + if [ "$CLEANUP_VOLUMES" = true ]; then + log WARN " → Entferne ungenutzte Volumes" + run_cmd docker volume prune -f >/dev/null 2>&1 + fi + + if [ "$CLEANUP_NETWORKS" = true ]; then + log INFO " → Entferne ungenutzte Netzwerke" + run_cmd docker network prune -f >/dev/null 2>&1 + fi + + after_size=$(get_docker_disk_usage) + + freed_space=$(awk "BEGIN {print $before_size - $after_size}") + + log INFO "✔️ Cleanup abgeschlossen (freigegeben: ${freed_space} MB)" + fi +fi + # ============================= # Notification # ============================= @@ -314,6 +389,10 @@ if [ "$NTFY_ENABLED" = true ]; then msg+=$'\n\n✔️ Alles aktuell' fi + if [ "$freed_space" != "0" ]; then + msg+=$'\n\n🧹 Cleanup: '"${freed_space} MB freigegeben" + fi + if [ "$NTFY_ONLY_ON_CHANGES" = false ] || \ [ ${#notify_stacks_updated[@]} -gt 0 ] || \ [ ${#notify_excluded_updates[@]} -gt 0 ] || \