Founder
Ubuntu 24.04 WSL2 Architecture: Preventing VHDX Bloat, Docker Sprawl, and Filesystem Corruption
Site Owner: Michael Baggett
Role: Project Developer
Joined: May 2023
Overview
This guide builds a modern Ubuntu 24.04 LTS environment on Windows Subsystem for Linux using an architecture specifically designed to avoid the most common long-term WSL problems:
- Massive
ext4.vhdxgrowth - WSL disks that never shrink
- Docker overlay storage explosion
- Filesystem corruption after disks reach 100%
- Slow exports and backups
- Runaway Linux page cache memory usage
- Windows PATH pollution inside Linux
- Poor separation between ephemeral and persistent data
This architecture keeps the Linux VHDX intentionally small while moving heavy persistent storage onto native Windows storage.
What Causes WSL Bloat?
The default WSL installation model encourages users to store everything inside the Linux filesystem:
- Git repositories
- Docker layers
- AI models
- datasets
- build artifacts
node_modules- databases
- caches
All of this lives inside:
ext4.vhdx
Over time:
- the VHDX grows continuously
- deleted files are not reclaimed efficiently
- Docker overlay2 storage becomes enormous
- filesystem corruption risk increases dramatically when disks fill completely
Once ext4 metadata corruption occurs after a 100% full condition, WSL may report massive phantom usage that cannot be reclaimed normally.
This guide avoids that entirely.
Architecture Goals
This deployment strategy:
- Keeps the Linux root filesystem lightweight
- Externalizes heavy persistent data
- Keeps Docker storage outside the VHDX
- Makes backups/export simple
- Reduces corruption risk
- Keeps compaction effective
- Provides predictable long-term performance
Recommended Storage Layout
C:\WSL\
├── Ubuntu\
│ └── ext4.vhdx
├── docker-data\
├── repos\
├── models\
├── datasets\
├── builds\
├── cache\
└── Backups\
Requirements
- Windows 11 Pro
- WSL 2.6+ recommended
- Administrative PowerShell access
- SSD/NVMe strongly recommended
Step 1 — Verify WSL and Windows Versions
This architecture depends on modern WSL2 features that improve:
- memory reclaim
- VHD behavior
- networking
- Docker stability
- filesystem performance
Minimum Recommended Versions
| Component | Recommended |
|---|---|
| Windows | Windows 11 23H2 or newer |
| WSL | 2.6.x or newer |
| WSL Kernel | 6.6.x or newer |
Verify Versions
Open PowerShell as Administrator:
wsl --version
Example healthy output:
WSL version: 2.6.3.0
Kernel version: 6.6.87.2-1
Then verify Windows version:
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
Example:
OS Name: Microsoft Windows 11 Pro
OS Version: 10.0.26200
Why This Matters
This guide uses modern WSL capabilities including:
- mirrored networking
- automatic memory reclaim
- improved VHD handling
- modern systemd support
Older WSL versions may:
- ignore some settings
- have networking issues
- leak memory more aggressively
- exhibit worse VHD growth behavior
If your WSL version is older than 2.6.x, update WSL before continuing:
wsl --update
Then reboot Windows.
Step 2 — Configure Global WSL Settings
Create:
C:\Users\<USERNAME>\.wslconfig
Contents:
[wsl2]
memory=16GB
processors=8
swap=8GB
swapFile=C:\\WSL\\swap.vhdx
networkingMode=mirrored
dnsTunneling=true
firewall=true
[experimental]
sparseVhd=true
autoMemoryReclaim=gradual
Step 3 — Reload WSL Configuration
wsl --shutdown
Step 4 — Install Ubuntu 24.04 LTS
wsl --install Ubuntu-24.04 --no-launch
Verify:
wsl --list --verbose
Step 5 — Relocate Ubuntu Outside AppData
wsl --export Ubuntu-24.04 C:\WSL\ubuntu24.tar
wsl --unregister Ubuntu-24.04
wsl --import Ubuntu C:\WSL\Ubuntu C:\WSL\ubuntu24.tar --version 2
Step 6 — Launch Ubuntu
wsl -d Ubuntu
Step 7 — Create the Permanent Linux User
adduser <USERNAME>
usermod -aG sudo <USERNAME>
Verify:
id <USERNAME>
Step 8 — Configure /etc/wsl.conf
sudo nano /etc/wsl.conf
Contents:
[boot]
systemd=true
[user]
default=<USERNAME>
[automount]
enabled=true
root=/mnt/
options="metadata,umask=22,fmask=11"
[interop]
enabled=true
appendWindowsPath=false
[network]
generateHosts=true
generateResolvConf=true
Step 9 — Restart WSL
wsl --shutdown
Reopen Ubuntu:
wsl -d Ubuntu
Verify:
whoami
systemctl is-system-running
echo $PATH
Step 10 — Configure Linux Directory Layout
mkdir -p ~/repos
mkdir -p ~/projects
mkdir -p ~/bin
Create symlinks:
ln -s /mnt/c/WSL/repos ~/winrepos
ln -s /mnt/c/WSL/models ~/models
ln -s /mnt/c/WSL/datasets ~/datasets
ln -s /mnt/c/WSL/builds ~/builds
ln -s /mnt/c/WSL/cache ~/cache
Step 11 — Install Docker Correctly
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin
Step 12 — Externalize Docker Storage
sudo nano /etc/docker/daemon.json
Contents:
{
"data-root": "/mnt/c/WSL/docker-data",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"features": {
"buildkit": true
}
}
Step 13 — Enable Docker
sudo systemctl enable docker
sudo systemctl restart docker
sudo usermod -aG docker <USERNAME>
Exit WSL:
exit
Shutdown WSL:
wsl --shutdown
Reopen Ubuntu:
wsl -d Ubuntu
Verify Docker:
docker version
docker info | grep "Docker Root Dir"
Expected:
Docker Root Dir: /mnt/c/WSL/docker-data
Final Validation
df -h /
docker system df
Example expected healthy output:
Filesystem Size Used Avail Use% Mounted on
/dev/sdd 1007G 2.0G 954G 1% /
Operational Best Practices
DO NOT Store These Inside Linux Home
Avoid:
- large Git repositories
- AI models
- Docker data
- databases
- build outputs
- huge caches
inside:
/home/<user>
DO Store Outside the VHDX
Store these in:
C:\WSL\
Examples:
- repositories
- datasets
- AI models
- build artifacts
- Docker layers
- caches
Recommended VS Code Workflow
Open repositories from:
/mnt/c/WSL/repos
NOT:
~/repos
Backup Strategy
Monthly export:
wsl --export Ubuntu C:\WSL\Backups\ubuntu-$(Get-Date -Format yyyyMMdd).tar
Periodic Maintenance
wsl --shutdown
Then compact:
Optimize-VHD -Path "C:\WSL\Ubuntu\ext4.vhdx" -Mode Full
Final Result
This architecture provides:
- Minimal VHDX growth
- Safer Docker operation
- Better long-term stability
- Easier backup/recovery
- Better filesystem health
- Easier storage management
- Lower corruption risk
- Cleaner Linux/Windows separation
Posted: