Docker Cleanup richtig automatisieren: Images, Volumes, Networks
AI generated
Docker · Cleanup · Automatisierung · CI/CD · Storage
Docker Cleanup richtig automatisieren
Images, Volumes und Networks sicher bereinigen

Ohne systematischen Docker Cleanup füllen sich CI-Runner und Produktionsserver innerhalb von Wochen mit ungenutzten Images, verwaisten Volumes und veralteten Build-Caches. Das richtige Automatisierungskonzept verhindert Disk-Volllauf, ohne versehentlich wichtige Daten zu löschen.

12 Min. Lesezeit system prune · image prune · volume prune · network prune · Cron-Jobs Docker 24+ · CI-Runner · Linux-Server · Produktion

1. Das Docker-Disk-Problem: woher kommt der Speicherverbrauch?

Docker akkumuliert Speicher in vier Kategorien: Images, Container, Volumes und der Build-Cache. Images sind die größte und am schnellsten wachsende Kategorie auf CI-Servern, wo täglich mehrere Builds neue Image-Tags erzeugen. Jeder docker build-Aufruf, der keinen Layer-Cache treffen kann, fügt neue Layer hinzu. Wird das alte Image nicht mehr referenziert, aber auch nicht explizit gelöscht, wird es zum dangling Image – sichtbar als Image ohne Tag in docker images. Diese Phantom-Images können sich innerhalb weniger Tage auf einem aktiven CI-Runner auf mehrere Gigabytes summieren.

Volumes sind das heimtückischste Cleanup-Problem. Ein Docker Cleanup mit docker system prune löscht standardmäßig keine Volumes – das ist bewusst, um versehentliche Datenverluste zu verhindern. Aber anonyme Volumes, die von Containern erzeugt wurden, die längst gelöscht sind, bleiben zurück und füllen den Disk-Space still und leise auf. Auf Produktionsservern können verwaiste Datenbank-Volumes, Test-Volumes und temporäre Volumes von gestoppten Compose-Projekten über Monate hinweg erheblichen Speicher belegen.

2. docker system df: aktuellen Speicherverbrauch verstehen

docker system df ist das erste Werkzeug für systematischen Docker Cleanup. Es zeigt eine Übersicht aller Ressourcen-Kategorien mit Gesamtgröße, aktivem Anteil und dem reclaimable Speicher – also dem, was durch Cleanup freigegeben werden kann. Mit docker system df -v (verbose) listet es alle einzelnen Ressourcen auf: jedes Image mit seiner Größe, jeden Container mit seinem Disk-Footprint, jedes Volume mit seiner Belegung. Diese Ausgabe zeigt sofort, wo die größten Einsparpotenziale liegen.

Ein wichtiger Unterschied, den docker system df beim Docker Cleanup deutlich macht: Image-Größe und tatsächlicher Disk-Verbrauch können erheblich divergieren, weil Docker-Images Layer teilen. Wenn zwei Images denselben Base-Layer nutzen, wird dieser nur einmal gespeichert. Das bedeutet, dass das Löschen eines einzigen großen Images unter Umständen nur wenige hundert Megabyte freigibt, wenn die meisten Layer von anderen Images geteilt werden. docker system df zeigt diese Realität korrekt im Shared-Size-Feld.


# Overview: total, active, and reclaimable disk usage per resource type
docker system df

# Verbose: list all individual resources with their sizes
docker system df -v

# Quick summary: how much can be reclaimed right now?
docker system df --format "table { {.Type} }\t{ {.TotalCount} }\t{ {.Size} }\t{ {.Reclaimable} }"

# Find the largest images (sorted by size)
docker images --format "{ {.Size} }\t{ {.Repository} }:{ {.Tag} }\t{ {.ID} }" \
  | sort -rh | head -20

# Find dangling images (untagged, not referenced by any container)
docker images -f dangling=true

# Find images older than 7 days (good candidates for cleanup)
docker images --format "{ {.CreatedSince} }\t{ {.Repository} }:{ {.Tag} }\t{ {.Size} }" \
  | grep -E "week|month|year"

3. Images bereinigen: dangling und veraltete Tags sicher entfernen

Dangling Images – also Images ohne Tag und ohne referenzierende Container – sind die sicherste Kategorie für Docker Cleanup. Mit docker image prune werden ausschließlich diese ungenutzten Zwischen-Layer gelöscht. Kein laufender Container, kein getaggtes Image wird angefasst. Das ist der konservativste und sicherste Cleanup-Schritt und kann problemlos täglich automatisiert werden. Auf einem aktiven CI-Runner mit mehreren Builds pro Tag können täglich mehrere Gigabyte durch dangling Image Cleanup freigegeben werden.

Für aggressiveres Docker Cleanup bietet docker image prune -a das Löschen aller Images, die nicht von einem laufenden oder gestoppten Container referenziert werden. Das betrifft also auch getaggte Images, die nicht aktiv in einem Container laufen. Mit dem Filter --filter until=72h werden nur Images entfernt, die älter als 72 Stunden sind – aktuell verwendete Images bleiben erhalten. Diese Kombination ist ideal für CI-Runner, die immer die neuesten Images bauen und ältere Versionen nicht länger brauchen.

4. Volumes bereinigen: verwaiste Daten ohne Datenverlust löschen

Docker Cleanup für Volumes erfordert mehr Sorgfalt als für Images, weil Volumes persistente Daten enthalten. docker volume prune löscht nur anonyme Volumes, die nicht von einem laufenden oder gestoppten Container referenziert werden. Named Volumes, die in Compose-Projekten oder mit explizitem Namen erstellt wurden, werden nicht gelöscht. Das ist die wichtige Sicherheitsnetz-Funktion: Eine Datenbank, deren Daten in einem Named Volume liegen (z.B. mysql-data), ist durch docker volume prune nicht gefährdet.

Vor jedem produktiven Docker Cleanup für Volumes empfiehlt sich docker volume ls mit einem Blick auf die Volume-Namen. Named Volumes wie project_mysql-data, project_redis-data oder project_uploads sind eindeutig identifizierbar und werden von docker volume prune nicht berührt. Anonyme Volumes haben lange, zufällige Hashes als Namen. Mit docker volume ls -f dangling=true werden nur nicht-referenzierte Volumes angezeigt – das ist die sichere Vorschau vor dem eigentlichen Cleanup.


#!/usr/bin/env bash
# docker-cleanup.sh — Safe, automated Docker cleanup script
set -euo pipefail

echo "=== Docker Disk Usage Before Cleanup ==="
docker system df

echo ""
echo "=== Step 1: Remove dangling images (safe, no data loss) ==="
docker image prune -f

echo ""
echo "=== Step 2: Remove stopped containers older than 24h ==="
docker container prune -f --filter until=24h

echo ""
echo "=== Step 3: Remove unused networks ==="
docker network prune -f

echo ""
echo "=== Step 4: Remove build cache older than 48h ==="
docker buildx prune -f --filter until=48h

echo ""
echo "=== Step 5: Remove anonymous volumes not referenced by any container ==="
# Preview first
DANGLING_VOLUMES=$(docker volume ls -qf dangling=true | wc -l)
echo "Found ${DANGLING_VOLUMES} dangling volumes to remove"
docker volume prune -f

echo ""
echo "=== Docker Disk Usage After Cleanup ==="
docker system df

5. Networks und Build-Cache aufräumen

Unused Docker Networks entstehen vor allem, wenn Compose-Projekte gestartet und wieder gestoppt werden, ohne dass die Networks explizit entfernt werden. docker compose down ohne das Flag --volumes lässt die Networks standardmäßig stehen. Mit docker network prune werden alle Networks entfernt, die von keinem laufenden Container verwendet werden. Das ist sicher, weil Docker automatisch ein neues Network erstellt, wenn ein Compose-Projekt oder Container es braucht. Das Limit von 31 benutzerdefinierten Bridge-Networks pro Host (ein Linux-Netzwerkbeschränkung) kann zu Fehlern führen, wenn Docker Cleanup für Networks vernachlässigt wird.

Der Build-Cache ist nach Images oft der zweitgrößte Speicherverbraucher. Mit docker buildx prune lässt sich der BuildKit-Cache gezielt bereinigen. Ohne Filter löscht es den gesamten Cache – das bedeutet, dass der nächste Build alle Layer neu erzeugen muss. Mit --filter until=48h werden nur Cache-Einträge entfernt, die älter als 48 Stunden sind. Auf CI-Runnern, die BuildKit-Cache für schnelle Builds nutzen, ist das die sinnvollere Option für den automatisierten Docker Cleanup, weil der aktuelle Cache für laufende oder geplante Jobs erhalten bleibt.

6. docker system prune: das große Aufräumen sicher einsetzen

docker system prune ist der mächtigste, aber auch riskanteste Docker Cleanup-Befehl. Er löscht in einem Schritt: gestoppte Container, dangling Images, nicht genutzte Networks und den Build-Cache. Mit -a zusätzlich alle ungenutzten Images. Mit --volumes sogar alle ungenutzten Volumes. Der Befehl fragt interaktiv nach Bestätigung, die mit -f (force) übersprungen werden kann – für Automatisierung nötig, aber mit Bedacht einzusetzen.

Die wichtigste Regel beim Docker Cleanup mit system prune: niemals --volumes auf einem Produktionsserver automatisiert laufen lassen, ohne vorher sicherzustellen, dass alle relevanten Volumes Named Volumes sind und in einem Backup erfasst sind. Anonyme Volumes auf einem Produktionsserver können Daten enthalten, die zwar kein aktiver Container referenziert, die aber trotzdem wichtig sind – etwa Volumes von gestoppten Containern, die nur für Wartungsarbeiten pausiert wurden. Mit docker ps -a vorher prüfen, ob gestoppte Container vorliegen, die noch relevante Daten in Volumes haben.


# Aggressive cleanup for CI runners: remove all unused images older than 3 days
# Safe: running containers and their images are never touched
docker image prune -a -f --filter until=72h

# Remove all images not used by any container (use with caution on production)
docker image prune -a -f

# system prune without volumes (recommended for automation)
docker system prune -f --filter until=24h

# Full system prune including volumes — ONLY on disposable CI runners
# NEVER run this unattended on production servers
docker system prune -af --volumes

# Clean up Compose project completely (containers, networks, volumes)
docker compose -f docker-compose.yml down --volumes --remove-orphans

# List named volumes before any cleanup — verify nothing important is anonymous
docker volume ls --format "table { {.Name} }\t{ {.Driver} }\t{ {.Mountpoint} }"

7. Docker Cleanup auf CI-Runnern automatisieren

CI-Runner sind die Umgebungen, in denen Docker Cleanup am dringendsten und gleichzeitig am sichersten zu automatisieren ist. Jeder Build kann neue Images, Container und Build-Caches erzeugen. Ohne regelmäßiges Cleanup sind Runner-Disks innerhalb von 1–2 Wochen voll. Die ideale Strategie: nach jedem CI-Job werden die Container und Netzwerke des Jobs aufgeräumt (via Compose-Down im Job selbst), täglich werden dangling Images und ältere ungenutzte Images via Cron entfernt, wöchentlich wird ein aggressiverer Cleanup mit docker system prune -af --filter until=24h durchgeführt.

Für GitLab CI und GitHub Actions gibt es außerdem die Möglichkeit, den Docker Cleanup direkt in der Pipeline zu verankern: ein Cleanup-Stage am Ende jeder Pipeline, der von den eigentlichen Build-Jobs getrennt ist und immer läuft (mit when: always in GitLab oder if: always() in GitHub Actions). Das stellt sicher, dass selbst bei fehlgeschlagenen Jobs keine unbegrenzt wachsenden Cleanup-Schulden entstehen. Der Cleanup-Job selbst muss keine Fehler verursachen – er kann mit || true oder continue-on-error: true abgesichert werden.

8. Docker Cleanup auf Produktionsservern: was ist sicher?

Auf Produktionsservern ist der Docker Cleanup konservativer anzugehen. Laufende Container und ihre Images dürfen nie entfernt werden. Gestoppte Container auf einem Produktionsserver können laufende Dienste sein, die temporär gestoppt wurden. Named Volumes enthalten persistente Daten. Der einzige sichere automatisierte Docker Cleanup auf Produktionsservern ist das Entfernen von dangling Images (docker image prune -f) und ungenutzten Networks (docker network prune -f). Beide Operationen berühren keine laufenden Container und keine persistenten Daten.

Für das Entfernen alter Images auf Produktionsservern empfiehlt sich eine manuelle oder halbautomatische Strategie: Nach einem Deployment des neuen Images prüfen, ob das alte Image noch von einem Container referenziert wird. Wenn nicht, kann es entfernt werden. Ein Cron-Job mit docker image prune -f (nur dangling) ist sicher. Ein Cron-Job mit docker image prune -a -f (alle ungenutzten) ist auf Produktionsservern risikoreicher und sollte mindestens mit --filter until=168h (eine Woche) eingeschränkt werden, um genug Zeit für Rollback-Szenarien zu lassen.

9. Cleanup-Strategien im Vergleich

Die verschiedenen Docker Cleanup-Befehle und -Strategien haben unterschiedliche Aggressivitätsstufen und Sicherheitsprofile. Die Wahl der richtigen Strategie hängt von der Umgebung (CI-Runner vs. Produktionsserver) und der Toleranz für Rebuild-Zeit ab.

Befehl Was wird gelöscht Sicher auf Produktion? Empfehlung CI-Runner
image prune Nur dangling Images Ja Täglich via Cron
image prune -a Alle ungenutzten Images Mit until-Filter Täglich mit until=72h
volume prune Anonyme, unref. Volumes Nur wenn klar anonym Wöchentlich nach Prüfung
system prune Container, Images, Netzwerke, Cache Ohne --volumes ja Wöchentlich
system prune --volumes Alles inkl. Volumes Nein Nur disposable Runner

Der goldene Mittelweg für automatisierten Docker Cleanup: docker image prune -f täglich für dangling Images, docker system prune -f --filter until=24h wöchentlich für Container, Networks und alten Cache. Volume-Cleanup nur manuell oder nach Prüfung. Auf CI-Runnern kann aggressiver vorgegangen werden, auf Produktionsservern immer konservativer.

Mironsoft

Docker-Infrastruktur, CI/CD-Automatisierung und Server-Betrieb

Docker-Server ohne Disk-Volllauf?

Wir richten automatisierte Docker-Cleanup-Strategien ein, die CI-Runner und Produktionsserver dauerhaft frei halten – ohne versehentliche Datenverluste, mit klarer Trennung nach Umgebung und Sicherheitsstufe.

Cleanup-Audit

Analyse des aktuellen Speicherverbrauchs und Identifikation der größten Einsparpotenziale

Cron-Automatisierung

Maßgeschneiderte Cleanup-Skripte mit Logging und Alerting für CI und Produktion

Registry-Cleanup

Automatisches Löschen veralteter Image-Tags in privaten Docker-Registries

10. Zusammenfassung

Systematischer Docker Cleanup beginnt mit dem Verständnis, welche Ressourcen-Kategorie den meisten Speicher belegt. docker system df -v liefert diese Übersicht in Sekunden. Die sicherste Cleanup-Kategorie sind dangling Images, gefolgt von ungenutzten Networks und gestoppten Containern. Volumes erfordern die größte Sorgfalt, weil sie persistente Daten enthalten. Named Volumes sind durch docker volume prune geschützt – nur anonyme Volumes werden entfernt.

Für die Automatisierung gilt die Devise: CI-Runner können aggressiver bereinigt werden, weil sie disposable sind und Images neu gezogen werden können. Produktionsserver brauchen konservativere Strategien mit until-Filtern und Fokus auf dangling Images und Networks. Ein täglich laufender Cron-Job mit docker image prune -f verhindert die Akkumulation von dangling Images auf jedem Docker-Host. Die Kombination aus gezieltem Docker Cleanup pro Kategorie und regelmäßiger Überprüfung mit docker system df hält Docker-Hosts dauerhaft gesund.

Docker Cleanup automatisieren — Das Wichtigste auf einen Blick

Diagnose zuerst

docker system df -v zeigt Gesamtverbrauch und reclaimable Speicher pro Kategorie. Immer vor dem Cleanup ausführen.

Dangling Images täglich

docker image prune -f ist der sicherste Cleanup-Schritt. Für CI täglich via Cron einrichten.

Volumes mit Vorsicht

docker volume prune löscht nur anonyme Volumes. Named Volumes sind geschützt. Vorher docker volume ls prüfen.

system prune safe

system prune -f --filter until=24h für Automatisierung. Niemals --volumes unbeaufsichtigt auf Produktionsservern.

11. FAQ: Docker Cleanup automatisieren

1Was sind dangling Images?
Image-Layer ohne Tag, nicht von einem Container referenziert. docker image prune entfernt ausschließlich diese Kategorie – der sicherste Cleanup-Schritt.
2Löscht volume prune Named Volumes?
Nein. Nur anonyme, nicht referenzierte Volumes werden entfernt. Named Volumes (mysql-data, redis-data) bleiben erhalten.
3Was zeigt docker system df?
Gesamtverbrauch, aktiver Anteil und reclaimable Speicher pro Ressourcen-Kategorie. Mit -v listet es alle einzelnen Ressourcen auf.
4system prune auf Produktion sicher?
Ohne --volumes ja, mit until-Filter. Niemals --volumes automatisiert auf Produktionsservern – manuelle Prüfung vorher.
5Cleanup via Cron einrichten?
0 3 * * * /usr/local/bin/docker-cleanup.sh in crontab. Täglich dangling Images, wöchentlich system prune ohne --volumes.
6Build-Cache-Wachstum begrenzen?
docker buildx prune --filter until=48h entfernt nur alten Cache. GitHub Actions Cache-Backend begrenzt automatisch.
7Network-Limit (31) erreicht?
docker network prune -f entfernt alle unbenutzten Networks sofort. Regelmäßiger Cleanup verhindert diesen Fehler.
8Anonyme vs. Named Volumes unterscheiden?
Named Volumes: beschreibende Namen. Anonyme Volumes: 64-stellige Hex-Hashes. docker volume ls -f dangling=true zeigt nur nicht-referenzierte.
9Minimale Disk-Reserve auf Docker-Hosts?
Mindestens 20%, besser 30% frei. Unter 10% schlagen Docker-Operationen mit unpräzisen Fehlern fehl.
10Cleanup in GitLab CI integrieren?
cleanup-Stage mit when: always und allow_failure: true am Ende der Pipeline. docker system prune -f --filter until=24h als Skript.