Alte Images und Container automatisch bereinigen

Alte Images und Container automatisch bereinigen

Docker häuft still Gigabytes an unbenutzten Images, gestoppten Containern und verwaisten Volumes an – ohne automatische Bereinigung ist eine volle Disk nur eine Frage der Zeit.

Das Problem

Bei jedem docker compose pull && docker compose up -d werden neue Images gezogen. Die alten Images bleiben erhalten – sie sind nicht mehr in Verwendung, belegen aber weiterhin Speicherplatz. Bei täglichen Deployments summiert sich das schnell.

# Aktuellen Verbrauch prüfen
docker system df

Methode 1: Watchtower --cleanup

Wenn Watchtower sowieso läuft, löscht es mit WATCHTOWER_CLEANUP: "true" das alte Image automatisch nach jedem Update:

services:
  watchtower:
    image: containrrr/watchtower
    environment:
      WATCHTOWER_CLEANUP: "true"

Einfach, automatisch, keine weitere Konfiguration nötig.

Methode 2: Cron-Job mit prune

# /etc/cron.d/docker-cleanup
# Täglich um 2:30 Uhr: Images die älter als 7 Tage sind löschen
30 2 * * * root docker image prune -a --filter "until=168h" -f >> /var/log/docker-cleanup.log 2>&1

# Gestoppte Container täglich aufräumen
30 2 * * * root docker container prune --filter "until=24h" -f >> /var/log/docker-cleanup.log 2>&1

--filter "until=168h" verhindert, dass Images gelöscht werden die gerade aktiv genutzt werden – nur Images die seit mindestens 7 Tagen nicht verwendet wurden, werden entfernt.

Methode 3: docker system prune mit Filter

# Alles was älter als 24h und ungenutzt ist bereinigen (ohne Volumes)
docker system prune --filter "until=24h" -f

# Mit Volumes (Vorsicht – prüfen was gelöscht wird!)
docker system prune -a --volumes --filter "until=168h" -f

Compose: Immer aktuellstes Image nutzen

# Pull zieht neues Image, up -d erstellt Container neu
# Das alte Image wird dann "dangling" und kann sicher gelöscht werden
docker compose pull
docker compose up -d
docker image prune -f  # Nur dangling Images – sicher

Retention Policy: Letzte N Images behalten

Wenn man die letzten 3 Versionen eines Images behalten will:

#!/bin/bash
# Alle Images eines Repository auflisten, sortiert nach Erstellungsdatum
# Alle außer den letzten 3 löschen
IMAGE_REPO="myregistry/myapp"

docker images "$IMAGE_REPO" --format "{{.ID}} {{.CreatedAt}}" \
  | sort -k2 -r \
  | tail -n +4 \
  | awk '{print $1}' \
  | xargs -r docker rmi

Sicher prüfen bevor man löscht

# Was würde gelöscht? (Dry-run existiert nicht, aber erst anschauen)
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.CreatedSince}}\t{{.Size}}"

# Dangling Images anzeigen (safe to delete)
docker images -f dangling=true

# Bilder ohne laufenden Container (potenziell löschbar)
docker images -f "dangling=false" | grep -v REPOSITORY

Warnung: prune -a vs prune

# Nur dangling (ungetaggte) Images – sehr sicher
docker image prune -f

# ALLE unbenutzten Images – auch getaggte ohne laufenden Container
docker image prune -a -f

-a löscht auch Images von gestoppten Containern. Wenn ein Container mit --restart=unless-stopped konfiguriert ist und gerade gestoppt ist (z.B. nach Neustart), löscht -a sein Image. Dann startet der Container nicht mehr. Im Zweifelsfall ohne -a arbeiten.