544 GB Docker – und nur 140 GB echte Daten

ContainerizationSoftware EngineeringSystem Engineering

Ich wollte eigentlich nur kurz prüfen, wo auf meiner Festplatte der Platz hingeht. WinDirStat ist dafür seit Jahren mein erster Griff: ein Scan, ein Treemap, und die grössten Brocken springen dir ins Gesicht.

Diesmal war es ein einziger Block — dunkelblau, riesig, unübersehbar:

C:\Users\<user>\AppData\Local\Docker\wsl\disk\docker_data.vhdx544 GB.

Fast ein Drittel meiner gesamten Festplatte. In einer Datei. Für Docker.

Gleichzeitig zeigte Docker Desktop in der Images-Ansicht etwas völlig anderes: Dutzende Einträge mit Name und Tag <none>, jeweils 11,6 GB gross. Sah aus wie Datenmüll — und war es auch. Aber nicht in der Grössenordnung, die die Oberfläche suggerierte.

Das war der Auslöser für eine Reise von der Verdachtsmeldung bis zur automatisierten Lösung.

Was WinDirStat wirklich zeigt

WinDirStat misst die Dateigrösse auf Windows. Bei docker_data.vhdx handelt es sich um die virtuelle Festplatte, in der Docker Desktop unter WSL2 alle Images, Container und Volumes speichert.

Wichtig: Diese VHDX ist dynamisch. Sie wächst, wenn innen Daten hinzukommen — aber sie schrumpft nicht, wenn du innen wieder löschst. Sie bleibt auf dem bisherigen Maximum stehen, bis du sie explizit komprimierst.

Deshalb passt die Anzeige in Docker Desktop (z. B. «24 GB Images») nicht zu WinDirStat (544 GB). WinDirStat zählt die aufgeblähte Scheibe, nicht den aktuellen Inhalt.

Nach einer Analyse innen in der VM lag die Wahrheit bei ungefähr 140 GB echter Daten. Der Rest war leerer, aber reservierter Ballast — Platz, den Windows schon «verloren» hatte, obwohl Docker ihn intern nicht mehr brauchte.

Die drei Schuldigen

1. Ollama-Modelle (~93 GB)

Für lokale LLM-Tests und Modellvergleiche hatte ich über die Zeit 19 Modelle angesammelt: verschiedene Qwen-, Gemma-, Phi- und Ministral-Varianten in 7B bis 14B. Jedes einzelne sinnvoll im Moment des ollama pull — zusammen ein ganzer Speichersee im Ollama-Docker-Volume (~93 GB).

2. Image-Rebuilds (~12 GB pro Image, viele Schichten)

Ich entwickle mit einem grossen Backend-Image: CUDA, PyTorch, ML-Bibliotheken, Document-Parsing. Jedes docker compose build oder jeder Rebuild mit neuem Tag erzeugt ein frisches Image. Das alte verliert seinen Namen und taucht als <none> auf.

In Docker Desktop sieht jedes dieser Images wie 11,6 GB aus. Tatsächlich teilen sie sich fast alle Layer. Der echte Müll war nur etwa 1 GB, nicht 30 × 11 GB. Die UI ist hier leicht irreführend.

3. Build-Cache (~35 GB)

Hunderte Cache-Einträge von wiederholten Builds. docker system df meldete davon rund 20 GB als reclaimable — Platz, den Docker intern freigeben kann, aber den Windows erst nach einem Compact wieder sieht.

Erst verstehen, dann aufräumen

Bevor ich blind docker system prune -a ausführte, habe ich mir die Aufschlüsselung angesehen:

docker system df -v
docker images -a
docker volume ls

Und in WSL die tatsächliche Belegung der virtuellen Disk:

wsl -d docker-desktop -- df -h

Das war der entscheidende Moment: 544 GB Datei auf C: bei nur ~140 GB echtem Inhalt innen. Die Lücke war der nicht zurückgegebene Speicher.

Was sicher ist — und was nicht

BefehlSicher für laufenden Stack?
docker image pruneJa — nur untagged Dangling Images
docker builder pruneJa — Build-Cache
docker container pruneJa — gestoppte Container
docker volume pruneNein — löscht u. a. Ollama-Modelle, Datenbank-Volumes

Ich habe bewusst kein Volume-Prune gemacht. Die Ollama-Modelle und Datenbank-Daten bleiben erhalten.

Schritt 1: Innen aufräumen

docker image prune -f
docker builder prune -af
docker container prune -f

Ergebnis bei mir: etwa 36 GB weniger belegter Speicher innen in der VHDX.

Wichtig: Auf C: ändert sich dabei noch nichts. Das ist der Punkt, den viele übersehen.

Schritt 2: VHDX komprimieren

Dafür muss Docker Desktop und WSL vollständig gestoppt sein:

docker desktop stop
wsl --terminate docker-desktop
wsl --shutdown

Kurz warten, bis keine WSL-Distribution mehr «Running» ist (wsl -l -v). Dann mit Administratorrechten per diskpart:

select vdisk file="C:\Users\<user>\AppData\Local\Docker\wsl\disk\docker_data.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit

Bei älteren Docker-Desktop-Installationen kann der Pfad auch ...\Docker\wsl\data\ext4.vhdx heissen.

Ergebnis bei mir:

Grösse
Vorher (WinDirStat)544 GB
Nachher118 GB
Gewonnen~426 GB

Der Compact-Lauf dauerte gut 7–8 Minuten. Danach Docker Desktop wieder starten — mein Stack kam sauber hoch.

Sparse-Modus: damit es nicht sofort wieder passiert

Ohne Gegenmassnahme wächst die VHDX beim nächsten Build-Marathon genauso wieder. Ab WSL kann man den Sparse-Modus aktivieren — dann wird ungenutzter Platz bei WSL-Shutdown eher zurückgegeben:

wsl --manage docker-desktop --set-sparse true

Das ersetzt kein gelegentliches manuelles Compact nach grossen Aufräumaktionen. Aber es hilft im Alltag.

Automatisierung

Den Ablauf mache ich nicht jedes Mal von Hand durch. Ein PowerShell-Skript übernimmt:

  1. Prune — Images, Build-Cache, gestoppte Container (kein Volume-Prune)
  2. Stop — Docker Desktop + WSL shutdown
  3. Compactdiskpart auf docker_data.vhdx (UAC-Abfrage)
  4. Sparse — WSL Sparse-Modus aktivieren (Default)
  5. Restart — Docker Desktop wieder starten

Aufruf:

.\compact-docker-disk.ps1

Varianten:

.\compact-docker-disk.ps1 -WhatIf        # nur Vorschau
.\compact-docker-disk.ps1 -PruneOnly     # ohne Compact
.\compact-docker-disk.ps1 -DisableSparse # ohne Sparse-Modus
.\compact-docker-disk.ps1 -SkipRestart   # Compact ohne Neustart

Das Skript erkennt docker_data.vhdx und als Fallback ext4.vhdx automatisch unter %LOCALAPPDATA%\Docker\wsl\.

Takeaways

  1. WinDirStat zeigt die VHDX-Dateigrösse, nicht den Docker-Inhalt. Eine Diskrepanz von Faktor 3–4 ist bei WSL2-Docker normal, wenn nie komprimiert wurde.
  2. <none>-Images in Docker Desktop täuschen. Die 11-GB-Anzeige ist virtuell; geteilter Layer-Müll ist meist viel kleiner.
  3. docker system prune allein reicht auf Windows nicht. Ohne VHDX-Compact bleibt docker_data.vhdx auf dem alten Maximum.
  4. Niemals docker volume prune, wenn Ollama-Modelle oder Datenbank-Volumes wichtig sind.
  5. Nach vielen Rebuilds lohnt sich ein geplanter Compact — bei mir einmalig 426 GB zurück.

Wann lohnt sich der Aufwand?

SituationEmpfehlung
VHDX deutlich grösser als docker system dfCompact ausführen
Viele <none>-Images nach Rebuildsimage prune + ggf. Compact
Regelmässige lokale Image-BuildsMonatlich oder nach grossen Refactors
Ollama-Modell-Wechsel / A/B-TestsUngenutzte Modelle mit ollama rm löschen

Wenn du Docker Desktop auf Windows für lokale Entwicklung mit ML-Stacks oder häufigen Rebuilds nutzt: einmal WinDirStat, einmal docker system df -v, einmal compacten. Oft die schnellste Festplatten-Aufräumaktion des Jahres.