{"id":394,"date":"2026-09-17T15:42:38","date_gmt":"2026-09-17T15:42:38","guid":{"rendered":"https:\/\/www.fabricioruch.ch\/?p=394"},"modified":"2026-09-17T15:42:38","modified_gmt":"2026-09-17T15:42:38","slug":"544-gb-docker-und-nur-140-gb-echte-daten","status":"publish","type":"post","link":"https:\/\/www.fabricioruch.ch\/?p=394","title":{"rendered":"544 GB Docker \u2013 und nur 140 GB echte Daten"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ich wollte eigentlich nur kurz pr\u00fcfen, wo auf meiner Festplatte der Platz hingeht. WinDirStat ist daf\u00fcr seit Jahren mein erster Griff: ein Scan, ein Treemap, und die gr\u00f6ssten Brocken springen dir ins Gesicht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Diesmal war es ein einziger Block \u2014 dunkelblau, riesig, un\u00fcbersehbar:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>C:\\Users\\&lt;user&gt;\\AppData\\Local\\Docker\\wsl\\disk\\docker_data.vhdx<\/code> \u2014 <strong>544 GB<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fast ein Drittel meiner gesamten Festplatte. In einer Datei. F\u00fcr Docker.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gleichzeitig zeigte Docker Desktop in der Images-Ansicht etwas v\u00f6llig anderes: Dutzende Eintr\u00e4ge mit Name und Tag <code>&lt;none&gt;<\/code>, jeweils <strong>11,6 GB<\/strong> gross. Sah aus wie Datenm\u00fcll \u2014 und war es auch. Aber nicht in der Gr\u00f6ssenordnung, die die Oberfl\u00e4che suggerierte.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das war der Ausl\u00f6ser f\u00fcr eine Reise von der Verdachtsmeldung bis zur automatisierten L\u00f6sung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Was WinDirStat wirklich zeigt<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">WinDirStat misst die <strong>Dateigr\u00f6sse auf Windows<\/strong>. Bei <code>docker_data.vhdx<\/code> handelt es sich um die virtuelle Festplatte, in der Docker Desktop unter WSL2 alle Images, Container und Volumes speichert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wichtig: Diese VHDX ist <strong>dynamisch<\/strong>. Sie w\u00e4chst, wenn innen Daten hinzukommen \u2014 aber sie <strong>schrumpft nicht<\/strong>, wenn du innen wieder l\u00f6schst. Sie bleibt auf dem bisherigen Maximum stehen, bis du sie explizit komprimierst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Deshalb passt die Anzeige in Docker Desktop (z. B. \u00ab24 GB Images\u00bb) nicht zu WinDirStat (544 GB). WinDirStat z\u00e4hlt die <strong>aufgebl\u00e4hte Scheibe<\/strong>, nicht den <strong>aktuellen Inhalt<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nach einer Analyse innen in der VM lag die Wahrheit bei ungef\u00e4hr <strong>140 GB<\/strong> echter Daten. Der Rest war leerer, aber reservierter Ballast \u2014 Platz, den Windows schon \u00abverloren\u00bb hatte, obwohl Docker ihn intern nicht mehr brauchte.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die drei Schuldigen<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Ollama-Modelle (~93 GB)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr lokale LLM-Tests und Modellvergleiche hatte ich \u00fcber die Zeit <strong>19 Modelle<\/strong> angesammelt: verschiedene Qwen-, Gemma-, Phi- und Ministral-Varianten in 7B bis 14B. Jedes einzelne sinnvoll im Moment des <code>ollama pull<\/code> \u2014 zusammen ein ganzer Speichersee im <strong>Ollama-Docker-Volume<\/strong> (~93 GB).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Image-Rebuilds (~12 GB pro Image, viele Schichten)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Ich entwickle mit einem grossen Backend-Image: CUDA, PyTorch, ML-Bibliotheken, Document-Parsing. Jedes <code>docker compose build<\/code> oder jeder Rebuild mit neuem Tag erzeugt ein frisches Image. Das alte verliert seinen Namen und taucht als <code>&lt;none&gt;<\/code> auf.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Docker Desktop sieht jedes dieser Images wie <strong>11,6 GB<\/strong> aus. Tats\u00e4chlich teilen sie sich fast alle Layer. Der echte M\u00fcll war nur etwa <strong>1 GB<\/strong>, nicht 30 \u00d7 11 GB. Die UI ist hier leicht irref\u00fchrend.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Build-Cache (~35 GB)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Hunderte Cache-Eintr\u00e4ge von wiederholten Builds. <code>docker system df<\/code> meldete davon <strong>rund 20 GB<\/strong> als reclaimable \u2014 Platz, den Docker intern freigeben kann, aber den Windows erst nach einem Compact wieder sieht.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Erst verstehen, dann aufr\u00e4umen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor ich blind <code>docker system prune -a<\/code> ausf\u00fchrte, habe ich mir die Aufschl\u00fcsselung angesehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker system df -v\ndocker images -a\ndocker volume ls<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Und in WSL die tats\u00e4chliche Belegung der virtuellen Disk:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wsl -d docker-desktop -- df -h<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das war der entscheidende Moment: <strong>544 GB Datei auf C:<\/strong> bei nur <strong>~140 GB<\/strong> echtem Inhalt innen. Die L\u00fccke war der nicht zur\u00fcckgegebene Speicher.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Was sicher ist \u2014 und was nicht<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Befehl<\/th><th>Sicher f\u00fcr laufenden Stack?<\/th><\/tr><tr><td><code>docker image prune<\/code><\/td><td>Ja \u2014 nur untagged Dangling Images<\/td><\/tr><tr><td><code>docker builder prune<\/code><\/td><td>Ja \u2014 Build-Cache<\/td><\/tr><tr><td><code>docker container prune<\/code><\/td><td>Ja \u2014 gestoppte Container<\/td><\/tr><tr><td><code>docker volume prune<\/code><\/td><td><strong>Nein<\/strong> \u2014 l\u00f6scht u. a. Ollama-Modelle, Datenbank-Volumes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ich habe bewusst <strong>kein<\/strong> Volume-Prune gemacht. Die Ollama-Modelle und Datenbank-Daten bleiben erhalten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schritt 1: Innen aufr\u00e4umen<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>docker image prune -f\ndocker builder prune -af\ndocker container prune -f<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ergebnis bei mir: etwa <strong>36 GB<\/strong> weniger belegter Speicher <em>innen<\/em> in der VHDX.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wichtig: <strong>Auf C: \u00e4ndert sich dabei noch nichts.<\/strong> Das ist der Punkt, den viele \u00fcbersehen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schritt 2: VHDX komprimieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Daf\u00fcr muss Docker Desktop und WSL vollst\u00e4ndig gestoppt sein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker desktop stop\nwsl --terminate docker-desktop\nwsl --shutdown<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Kurz warten, bis keine WSL-Distribution mehr \u00abRunning\u00bb ist (<code>wsl -l -v<\/code>). Dann mit Administratorrechten per <code>diskpart<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>select vdisk file=\"C:\\Users\\&lt;user&gt;\\AppData\\Local\\Docker\\wsl\\disk\\docker_data.vhdx\"\nattach vdisk readonly\ncompact vdisk\ndetach vdisk\nexit<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Bei \u00e4lteren Docker-Desktop-Installationen kann der Pfad auch <code>...\\Docker\\wsl\\data\\ext4.vhdx<\/code> heissen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Ergebnis bei mir:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th><\/th><th>Gr\u00f6sse<\/th><\/tr><tr><td>Vorher (WinDirStat)<\/td><td><strong>544 GB<\/strong><\/td><\/tr><tr><td>Nachher<\/td><td><strong>118 GB<\/strong><\/td><\/tr><tr><td>Gewonnen<\/td><td><strong>~426 GB<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Der Compact-Lauf dauerte gut <strong>7\u20138 Minuten<\/strong>. Danach Docker Desktop wieder starten \u2014 mein Stack kam sauber hoch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sparse-Modus: damit es nicht sofort wieder passiert<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ohne Gegenmassnahme w\u00e4chst die VHDX beim n\u00e4chsten Build-Marathon genauso wieder. Ab WSL kann man den Sparse-Modus aktivieren \u2014 dann wird ungenutzter Platz bei <strong>WSL-Shutdown<\/strong> eher zur\u00fcckgegeben:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wsl --manage docker-desktop --set-sparse true<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das ersetzt kein gelegentliches manuelles Compact nach grossen Aufr\u00e4umaktionen. Aber es hilft im Alltag.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Automatisierung<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Den Ablauf mache ich nicht jedes Mal von Hand durch. Ein PowerShell-Skript \u00fcbernimmt:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Prune<\/strong> \u2014 Images, Build-Cache, gestoppte Container (kein Volume-Prune)<\/li>\n\n\n\n<li><strong>Stop<\/strong> \u2014 Docker Desktop + WSL shutdown<\/li>\n\n\n\n<li><strong>Compact<\/strong> \u2014 <code>diskpart<\/code> auf <code>docker_data.vhdx<\/code> (UAC-Abfrage)<\/li>\n\n\n\n<li><strong>Sparse<\/strong> \u2014 WSL Sparse-Modus aktivieren (Default)<\/li>\n\n\n\n<li><strong>Restart<\/strong> \u2014 Docker Desktop wieder starten<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Aufruf:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\\compact-docker-disk.ps1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Varianten:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\\compact-docker-disk.ps1 -WhatIf        # nur Vorschau\n.\\compact-docker-disk.ps1 -PruneOnly     # ohne Compact\n.\\compact-docker-disk.ps1 -DisableSparse # ohne Sparse-Modus\n.\\compact-docker-disk.ps1 -SkipRestart   # Compact ohne Neustart<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das Skript erkennt <code>docker_data.vhdx<\/code> und als Fallback <code>ext4.vhdx<\/code> automatisch unter <code>%LOCALAPPDATA%\\Docker\\wsl\\<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Takeaways<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>WinDirStat zeigt die VHDX-Dateigr\u00f6sse<\/strong>, nicht den Docker-Inhalt. Eine Diskrepanz von Faktor 3\u20134 ist bei WSL2-Docker normal, wenn nie komprimiert wurde.<\/li>\n\n\n\n<li><code>&lt;none><\/code><strong>-Images in Docker Desktop t\u00e4uschen.<\/strong> Die 11-GB-Anzeige ist virtuell; geteilter Layer-M\u00fcll ist meist viel kleiner.<\/li>\n\n\n\n<li><code>docker system prune<\/code> <strong>allein reicht auf Windows nicht.<\/strong> Ohne VHDX-Compact bleibt <code>docker_data.vhdx<\/code> auf dem alten Maximum.<\/li>\n\n\n\n<li><strong>Niemals<\/strong> <code>docker volume prune<\/code>, wenn Ollama-Modelle oder Datenbank-Volumes wichtig sind.<\/li>\n\n\n\n<li><strong>Nach vielen Rebuilds<\/strong> lohnt sich ein geplanter Compact \u2014 bei mir einmalig <strong>426 GB<\/strong> zur\u00fcck.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Wann lohnt sich der Aufwand?<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Situation<\/th><th>Empfehlung<\/th><\/tr><tr><td>VHDX deutlich gr\u00f6sser als <code>docker system df<\/code><\/td><td>Compact ausf\u00fchren<\/td><\/tr><tr><td>Viele <code>&lt;none&gt;<\/code>-Images nach Rebuilds<\/td><td><code>image prune<\/code> + ggf. Compact<\/td><\/tr><tr><td>Regelm\u00e4ssige lokale Image-Builds<\/td><td>Monatlich oder nach grossen Refactors<\/td><\/tr><tr><td>Ollama-Modell-Wechsel \/ A\/B-Tests<\/td><td>Ungenutzte Modelle mit <code>ollama rm<\/code> l\u00f6schen<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn du Docker Desktop auf Windows f\u00fcr lokale Entwicklung mit ML-Stacks oder h\u00e4ufigen Rebuilds nutzt: einmal WinDirStat, einmal <code>docker system df -v<\/code>, einmal compacten. Oft die schnellste Festplatten-Aufr\u00e4umaktion des Jahres.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich wollte eigentlich nur kurz pr\u00fcfen, wo auf meiner Festplatte der Platz hingeht. WinDirStat ist daf\u00fcr seit Jahren mein erster Griff: ein Scan, ein Treemap, und die gr\u00f6ssten Brocken springen dir ins Gesicht. Diesmal war es ein einziger Block \u2014 dunkelblau, riesig, un\u00fcbersehbar: C:\\Users\\&lt;user&gt;\\AppData\\Local\\Docker\\wsl\\disk\\docker_data.vhdx \u2014 544 GB. Fast ein Drittel meiner gesamten Festplatte. In einer [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[65,25,59],"tags":[],"class_list":["post-394","post","type-post","status-publish","format-standard","hentry","category-containerization","category-software-engineering","category-system-engineering"],"_links":{"self":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=394"}],"version-history":[{"count":1,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/394\/revisions"}],"predecessor-version":[{"id":395,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/394\/revisions\/395"}],"wp:attachment":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}