Before You Begin: Safety First
Rebuilding WSL2 means starting fresh. It deletes your current Linux distro, so preparation is key.
β οΈ Critical Warning
Commands like –unregister and Remove-Item are destructive.
Run them only after confirming your backups.Pre-flight Checklist
- You have backed up your WSL distro and $HOME.
- At least 50 GB free on your target drive (e.g., D:\).
- Running Windows 11 24H2 + WSL2 kernel 6.x.
- Youβll follow steps in order, without skipping.
How to Read Command Blocks
Throughout this guide youβll see environment icons:
Icon Context Example πͺ PowerShell (Windows) Run from Windows Terminal or PowerShell. π§ WSL (Ubuntu Terminal) Inside Ubuntu after typing wsl. π Root inside WSL Use sudo or sudo su.
Backup Your Environment if exists
π‘ Why this matters
Backups are your only safety net before unregistering or wiping WSL. You neeed to create firstD:\Backup folderπͺ PowerShell – backup all
wsl --export Ubuntu D:\Backup\ubuntu-backup.tarπ§ Inside WSL – backup only home
tar -cvf /mnt/d/Backup/home.tar /home/usernameβ Verify
dir D:\Backup\Both ubuntu-backup.tar and home.tar should exist.
Uninstall and Clean Up WSL
Confirm Before Proceeding
- Backups verified.
- All terminals closed.
- Docker not running.
πͺ PowerShell
wsl --unregister Ubuntu Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux Disable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatformπͺ Clean Residual Data
Remove-Item "$env:LOCALAPPDATA\Packages\Canonical*" -Recurse -Force Remove-Item "C:\Users\*\AppData\Local\lxss" -Recurse -Force -ErrorAction Ignoreβ Verify
wsl -l -vShould show no installed distros.
Reinstall WSL2 on a Custom Drive
π‘ Installing on D:\ avoids slow I/O and giant VHDX files.
πͺ PowerShell β enable WSL2
wsl --install wsl --set-default-version 2
πͺ PowerShell β create target folder
New-Item -ItemType Directory -Force -Path D:\WSL | Out-Null
πͺ PowerShell β download the official Ubuntu 24.04 WSL rootfs (amd64)
Invoke-WebRequest `https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz`Β -OutFile D:\WSL\ubuntu-noble-wsl-amd64.rootfs.tar.gz(If you’re on ARM64, replace the URL with …arm64-wsl.rootfs.tar.gz.)
πͺ PowerShell β import into a custom directory on D:\
wsl --import Ubuntu D:\WSL\Ubuntu D:\WSL\ubuntu-noble-wsl-amd64.rootfs.tar.gz --version 2
β Verify installation
wsl -d Ubuntu uname -aExpected output should include:
Linux ubuntu-dev … Ubuntu 24.04 LTS (Noble Numbat)
β (Optional but recommended) Verify SHA256 integrity:
Get-FileHash D:\WSL\ubuntu-noble-wsl-amd64.rootfs.tar.gz -Algorithm SHA256Compare with the SHA256SUMS file available at:
https://cloud-images.ubuntu.com/wsl/releases/24.04/current/SHA256SUMS
Restore previous /home backup into the new WSL install
π This assumes you created the backup earlier using:
tar -cvf /mnt/d/Backup/home.tar /home/username
πͺ PowerShell β copy backup into the new WSL distro
Copy-Item D:\Backup\home.tar D:\WSL\Ubuntu\home.tar(or move instead of copy if you prefer)
π§ Inside WSL β extract backup into /home
cd / sudo tar -xvf /home.tar -C /β This will recreate /home/walmirsilva/ exactly as it was.
π§ Fix user permissions (IMPORTANT)
sudo chown -R username:username /home/username
β Verify restored user files
ls -la /home/usernameβ If your shell, SSH keys, git config, nvm, composer, php tools, etc. are back β youβre good.
Common restore mistakes to avoid
Mistake Consequence Extracting inside /root instead of / User home ends up in the wrong place Forgetting sudo during restore Files owned by root, cannot edit Not running chown Permissions broken, apps fail silently Restoring while inside /home Nested folder /home/home/username gets created
Optional: delete the .tar after restore
sudo rm /home.tarEnable systemd, Mirrored Networking, Static DNS
π§ Inside WSL
sudo nano /etc/wsl.conf[boot] systemd=true [network] hostname=ubuntu-dev generateHosts=false networkingMode=mirrored dns=8.8.8.8πͺ PowerShell
wsl --shutdownβ Verify
systemctl list-units | headsystemd services should appear active.
Install Developer Essentials
π§ WSL
sudo apt update && sudo apt install -y \ build-essential git curl zip unzip zsh php8.4-cli php8.4-fpm php8.4-xml \ php8.4-mysql php8.4-redis php8.4-curl php8.4-intl php8.4-bcmathInstall Composer:
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composerβ Verify
php -v composer -V
Install Docker Engine (No Docker Desktop)
π‘ Why this matters
Native Docker inside WSL2 uses less memory and integrates with systemd.π§ WSL
curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USERπͺ Restart WSL
wsl --shutdownβ Verify
docker run --rm hello-world
Move Docker Data Outside WSL
π§ WSL
sudo systemctl stop docker sudo mv /var/lib/docker /mnt/d/DockerData sudo nano /etc/docker/daemon.json{ "data-root": "/mnt/d/DockerData" }sudo systemctl start dockerβ Verify
docker info | grep "Docker Root Dir"Should show /mnt/d/DockerData.
Control and Shrink Disk Growth
πͺ PowerShell
wsl --shutdown Optimize-VHD -Path "D:\WSL\Ubuntu\ext4.vhdx" -Mode FullOptional size limit:
Set-ItemProperty -Path "HKCU:\Software\Microsoft\WSL" -Name "vhdSize" -Value 80GBβ Verify
Check D:\WSL\Ubuntu\ext4.vhdx file size.
Configure Terminal & Shell
πͺ PowerShell
winget install JanDeDobbeleer.OhMyPoshπ§ WSL
chsh -s /usr/bin/zsh git clone https://github.com/zsh-users/zsh-autosuggestions ~/.zsh-autosuggestions git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.zsh-syntax-highlightingβ Verify
Restart terminal β prompt should be colorful with Git branch shown.
Git & GitFlow Automation
Why this matters:
GitFlow is not just a naming convention. It is an extension that provides workflow commands for managing features, releases, hotfixes, and version tagging. Using the plugin prevents merge mistakes and enforces a clean release cycle.
Install Git + GitFlow plugin
π§ WSL (Ubuntu)
sudo apt install git git-flowVerify installation:
git flow versionExpected output:
git-flow version 1.12.3 (AVH Edition)If you do not see the version, the plugin was not installed correctly.
Initialize GitFlow in a repository
π§ WSL
cd /path/to/your/project git flow initYou will be prompted to confirm branch names. Recommended defaults:
- Production branch: main
- Development branch: develop
- Feature prefix: feature/
- Release prefix: release/
- Hotfix prefix: hotfix/
- Support prefix: support/
- Version tag prefix: v
Just press Enter to accept the defaults unless your team uses a different structure.
Daily usage commands (Cheatsheet)
Create a new feature:
git flow feature start my-featureFinish a feature (auto-merge into develop):
git flow feature finish my-featureStart a release:
git flow release start 1.3.0Finish a release (merge into main, tag, and merge back into develop):
git flow release finish 1.3.0Start a production hotfix:
git flow hotfix start security-fixFinish a hotfix:
git flow hotfix finish security-fix
Optional quality-of-life aliases
π§ WSL
git config --global alias.co checkout git config --global alias.br branch git config --global alias.st status git config --global alias.lg "log --oneline --graph --decorate --all" git config --global core.autocrlf false
Verify setup
git flow init -h git flow feature list git flow release listIf all commands run without errors: GitFlow is working properly.
Important notes
- GitFlow is ideal for software that has release cycles β not for trunk-based deployment.
- Teams using GitHub Flow or GitLab Flow normally do not use GitFlow.
- GitFlow generates merge commits by design (not rebase-based).
- For semantic versioning, use tags like: v1.2.3.
Performance & Resource Limits
πͺ PowerShell
notepad "$env:USERPROFILE\.wslconfig"[wsl2] memory=8GB processors=6 swap=2GB localhostForwarding=trueβ Verify
wsl --statusConfirm config is applied.
Rollback / Recovery
πͺ Restore old distro
wsl --import Ubuntu D:\WSL\Ubuntu D:\Backup\ubuntu-backup.tar --version 2π§ Revert networking
sudo nano /etc/wsl.conf[network] networkingMode=natπͺ Remove broken install
wsl --unregister Ubuntuβ Keep your backups until everything runs stably.
Networking Troubleshooting
Symptom Solution Windows β WSL unreachable Use networkingMode=mirrored Docker DNS fails Use gateway.docker.internal Random DNS drops Add dns=8.8.8.8 Services missing Restart: sudo systemctl restart systemd-resolved π§ Diagnostics
cat /etc/resolv.conf
ip route show systemctl status docker journalctl -u docker
Security Basics
π§ Recommended layout
/etc/ssl/private/ app.key app.crt fullchain.pemTips
- Store SSH keys in ~/.ssh, not on /mnt/c.
- chmod 600 for private keys.
- .crt = public, .key = private, .pem = bundle.
- Consider enabling ufw for simple firewalling:
sudo apt install ufw && sudo ufw enable
Appendix β Templates & Scripts
/etc/wsl.conf
[boot] systemd=true [network] networkingMode=mirrored dns=8.8.8.8.wslconfig
[wsl2] memory=8GB processors=6 swap=2GB localhostForwarding=truedaemon.json
{ "data-root": "/mnt/d/DockerData" }backup_restore.ps1
param([string]$BackupPath = "D:\Backup\ubuntu-backup.tar") wsl --shutdown wsl --export Ubuntu $BackupPath Write-Host "Backup saved at $BackupPath"This guide transforms WSL2 from a fragile convenience layer into a reliable Linux workspace for enterprise-class development.
References
- Microsoft Learn β Accessing network applications with WSL
https://learn.microsoft.com/en-us/windows/wsl/networking (Microsoft Learn)- Microsoft Learn β Advanced settings configuration in WSL (.wslconfig and wsl.conf)
https://learn.microsoft.com/en-us/windows/wsl/wsl-config (Microsoft Learn)- Microsoft Learn β What is Windows Subsystem for Linux (WSL)
https://learn.microsoft.com/en-us/windows/wsl/about (Microsoft Learn)- Nick Janetakis β Install Docker in WSL2 without Docker Desktop
https://nickjanetakis.com/blog/install-docker-in-wsl-2-without-docker-desktop (Nick Janetakis)- Dev.to β WSL mirrored-mode networking in Docker Desktop 4.26.0
https://dev.to/docker/wsl-mirrored-mode-networking-in-docker-desktop-4260-4b86 (dev.to)
β¨ ConfianΓ§a Sempre β Build Smart, Build Safe!
Audience: Developers, DevOps engineers, backend architects
Goal: Rebuild a clean, predictable, high-performance WSL2 environment β with mirrored networking, Docker outside C:\, and zero ambiguity about where each command should run.

