Windows Subsystem for Linux (WSL) is a great technology for running Linux guests on Window 10 and Windows 11.
In the past, you could use hypervisor software like VMware vSphere or Oracle Virtualbox to run Linux guests, but starting with Windows 10, Microsoft has made great strides in joining the two NT and Linux kernels very seamlessly on Windows.
I generally use the same Ubuntu Linux guest for my daily work, however I also often need to record demo videos to hand off completed software projects to clients. For screenshare recordings, I want to be able to start from a clean slate to demonstrate all the installation steps and other tasks to bring up a codebase to development and production stages.
In this post, I share a few useful snippets for doing just that.
Don’t miss this companion video on YouTube — it covers everything discussed in this post.
base
Linux distributionThe following bash
snippet downloads the latest Ubuntu 24.20 [1] Linux distribution for WSL.
Note the use of these environmental shell variables that you may wish to update for your situation:
WINDOWS_VM_FOLDER
Windows location to save Linux guest machinesLINUX_MOUNT_VM_FOLDER
The mount path from Linux for guest machinesLINUX_GUEST_IMAGE_URL
Linux WSL distribution .tar.gz
archiveDISTRO_BASE
Name for the Linux base
templateDISTRO_NAME
Name for a new container created from base
Run the following commands in an already existing Linux guest to download the Ubuntu Linux image or alternately use a browser of your choice here.
# Linux guest
# or download the same URL using your browser
export LINUX_MOUNT_VM_FOLDER=/mnt/c/wsl2/
export LINUX_GUEST_IMAGE_URL="https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-amd64-24.04lts.rootfs.tar.gz"
cd /tmp
wget "${LINUX_GUEST_IMAGE_URL}" -O ubuntu.tar.gz
gunzip ubuntu.tar.gz
mv ubuntu.tar ${LINUX_MOUNT_VM_FOLDER}
Next, open a PowerShell terminal and import this new distribution:
# Windows host
$env:WINDOWS_VM_FOLDER = "C:\wsl2"
$env:DISTRO_BASE = "base"
wsl --import $env:DISTRO_BASE "$env:WINDOWS_VM_FOLDER\$env:DISTRO_BASE" "$env:WINDOWS_VM_FOLDER\ubuntu.tar" --version 2
rm "$env:WINDOWS_VM_FOLDER\ubuntu.tar"
wsl --distribution $env:DISTRO_BASE
This will launch the shell terminal for the newly created Linux guest. The foregoing would have created a new user named ubuntu
but you may wish to create your own:
# Linux guest
sudo adduser patrick
sudo addgroup docker
sudo addgroup dialup
sudo addgroup plugdev
sudo usermod -aG sudo,dialup,plugdev,docker patrick
You can also add a few handy executables to your $PATH
to make jumping between distros more speedy:
cd /usr/local/bin/
sudo ln -sf $(which powershell.exe) powershell
sudo ln -sf $(which cmd.exe) cmd
sudo ln -sf $(which wsl.exe) wsl
Before closing the distribution, we also want to update /etc/wsl.conf
[2] with some further settings:
# docs: https://learn.microsoft.com/en-us/windows/wsl/wsl-config
[boot]
systemd = true
[network]
hostname = base
[user]
default = patrick
Halt the distribution from PowerShell. Set a default user if you wish to change it to something other than ubuntu
. Wait 8 seconds[3], then re-launch it to make any further customization.
# Windows host
$env:DISTRO_BASE = "base"
wsl --terminate $env:DISTRO_BASE
# change user that is signed into
wsl --manage $env:DISTRO_BASE --set-default-user patrick
# wait 8 seconds and restart Linux guest
wsl --distribution $env:DISTRO_BASE
At this point, you now have a good base
Linux distribution that merely has a new user added to the superuser-do sudo
group and an updated /etc/hostname
for clarity.
Based on your use-case, you may now strategize how you want to layer your Linux templates. To wit:
base
Linux distribution with user and dotfiles setbase-rustlang
+ Rust build dependenciesbase-pyenv
+ Python dependenciesbase-stablediffusion
+ Stable Diffusion packagesFor my part, I continued configuring my base
template with my personal dotfiles
[4]. Then, when I'm recording videos for client documentation or tutorials I usually just start from there and take periodic snapshot exports.
With this layering in mind, I'll move on to demonstrate how to export snapshots of these Linux guests as you further configure your template distributions.
The jargon varies but basically the terms snapshot, template, image all refer to a specific state of the Linux root filesystem that can be exported using wsl.exe
.
When you have finished interactively configuring your Linux guest template, return to PowerShell and invoke these commands:
$env:DISTRO_BASE = "base"
$env:TEMPLATE_FILENAME = "C:\wsl2\template-base.vhdx"
wsl --shutdown
# --format can be any of: tar, tar.gz, vhd
wsl --export "$env:DISTRO_BASE" "$env:TEMPLATE_FILENAME" --format vhd
You may want to keep a single base
template for any and all uses, or snapshot more often.
To create a new Linux guest from a template:
$env:DISTRO_NAME = "hello-world"
$env:WINDOWS_VM_FOLDER = "C:\wsl2"
$env:TEMPLATE_FILENAME = "C:\wsl2\template-base.vhdx"
mkdir "$env:WINDOWS_VM_FOLDER\$env:DISTRO_NAME"
wsl --import "$env:DISTRO_NAME" `
"$env:WINDOWS_VM_FOLDER\$env:DISTRO_NAME\" `
"$env:TEMPLATE_FILENAME" `
--version 2 `
--vhd
And happily we indeed see our newly created container hello-world
which is a copy of our base
Linux template.
Visit the Ubuntu cloud images file directory to find the latest release.
Microsoft Learn: Advanced settings configuration in WSL
Microsft Learn, ibid: The 8 second rule for configuration changes
github.com/dotfiles: Your unofficial guide to Dotfiles