WSL2 Professional Rebuild Guide

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:

IconContextExample
πŸͺŸPowerShell (Windows)Run from Windows Terminal or PowerShell.
🐧WSL (Ubuntu Terminal)Inside Ubuntu after typing wsl.
πŸ”Root inside WSLUse 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 first D:\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 -v

Should 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 -a

Expected 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 SHA256

Compare 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

MistakeConsequence
Extracting inside /root instead of /User home ends up in the wrong place
Forgetting sudo during restoreFiles owned by root, cannot edit
Not running chownPermissions broken, apps fail silently
Restoring while inside /homeNested folder /home/home/username gets created

Optional: delete the .tar after restore

sudo rm /home.tar

Enable 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 | head

systemd 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-bcmath

Install 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 Full

Optional 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-flow

Verify installation:

git flow version

Expected 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 init

You 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-feature

Finish a feature (auto-merge into develop):

git flow feature finish my-feature

Start a release:

git flow release start 1.3.0

Finish a release (merge into main, tag, and merge back into develop):

git flow release finish 1.3.0

Start a production hotfix:

git flow hotfix start security-fix

Finish 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 list

If all commands run without errors: GitFlow is working properly.


Important notes

  1. GitFlow is ideal for software that has release cycles β€” not for trunk-based deployment.
  2. Teams using GitHub Flow or GitLab Flow normally do not use GitFlow.
  3. GitFlow generates merge commits by design (not rebase-based).
  4. 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 --status

Confirm 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

SymptomSolution
Windows ↔ WSL unreachableUse networkingMode=mirrored
Docker DNS failsUse gateway.docker.internal
Random DNS dropsAdd dns=8.8.8.8
Services missingRestart: 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.pem

Tips

  • 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=true

daemon.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


✨ 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.

Leave a Comment

Your email address will not be published. Required fields are marked *