Honestly, I love Docker. Long gone are the days of XAMPP and installing dependencies on my host machine, and it works so much better day to day than Vagrant ever did.
But even though I'm a Linux fan through and through, I still use Windows in my day to day development. So Docker Desktop on my host machine, WSL 2, with Ubuntu 24 running all my instances. Honestly, it works pretty well and I've been doing it this way since I left my old city (and work computer) behind.
But... WSL and Docker Desktop don't store files directly in NTFS
- they live inside giant .vhdx
virtual disks. What's more, when you delete stuff inside Ubuntu/Docker the space is freed inside ext4 but the .vhdx
file doesn't shrink; it only ever grows.
Over time, that leads to those hundreds of gigs just locked up in AppData
. The fix is to compact the VHDX files (with Optimize-VHD
or diskpart) after shutting down WSL/Docker, which reclaims the unused blocks and shrinks the files back down.
If you forget to do this occassionally like I do, here's a quick one liner that you can use in Powershell to inspect how much space is used.
@(
Get-ChildItem "$env:LOCALAPPDATA\Docker\wsl" -Filter *.vhdx -Recurse -ErrorAction SilentlyContinue
Get-ChildItem "$env:LOCALAPPDATA\Packages\*\LocalState\ext4.vhdx" -File -ErrorAction SilentlyContinue
) | Select-Object FullName, @{n='SizeGB';e={[math]::Round($_.Length/1GB,2)}} |
Sort-Object SizeGB -Descending
Note: You MAY need to adjust your paths.
Now obviously you may want to prune existing data - dangling docker volumes, images that are just sitting there collecting dust, but I needed space pronto - without affecting any used containers. So I skipped that step.
Then you want to kick off a new Elevated powershell terminal, and run this:
wsl --shutdown; Stop-Process -Name "Docker Desktop" -ErrorAction SilentlyContinue; $vhdx = @(Get-ChildItem "$env:LOCALAPPDATA\Docker\wsl" -Filter *.vhdx -Recurse -ErrorAction SilentlyContinue; Get-ChildItem "$env:LOCALAPPDATA\Packages\*\LocalState\ext4.vhdx" -File -ErrorAction SilentlyContinue); Write-Host "`nBefore:"; $vhdx | Select-Object FullName,@{n='SizeGB';e={[math]::Round($_.Length/1GB,2)}} | Sort-Object SizeGB -Descending; try { Import-Module Hyper-V -ErrorAction Stop; $vhdx | ForEach-Object { Write-Host "Optimizing $_.FullName"; Optimize-VHD -Path $_.FullName -Mode Full } } catch { Write-Warning "Hyper-V PowerShell module not available; falling back to diskpart"; $tmp=[IO.Path]::GetTempFileName(); Set-Content -Path $tmp -Value (($vhdx|ForEach-Object{"select vdisk file=""$($_.FullName)""`ncompact vdisk"}) -join "`r`n"); diskpart /s $tmp; Remove-Item $tmp -Force }; Write-Host "`nAfter:"; $vhdx | Select-Object FullName,@{n='SizeGB';e={[math]::Round((Get-Item $_.FullName).Length/1GB,2)}} | Sort-Object SizeGB -Descending
Obviously, don't run commands copied from the internet on your computer unless you know what they're doing. This will try to:
- Stop WSL
- Stop Docker Desktop
- Find
VHDX
files under common paths - Evaluate file size.
- Use Hyper-V PowerShell to resize each virtual disk; if not available, use diskpart
- Evaluate the files again to see how much space was cleared.
Then, go install the latest game you've been wanting to try.
Bloody hell I miss working on Linux. Powershell scripting is awful.
Top comments (0)