HomeBlogServicesContact
Home
Blog
Services
Contact
  1. Home/
  2. Backstage Blog/
  3. Build a Template for Linux Guests on WSL2
Build a Template for Linux Guests on WSL2
Author avatar
Patrick Paul•Follow on
February 24, 2025
Backstage

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.

Creating a new base Linux distribution

The 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 machines
  • LINUX_MOUNT_VM_FOLDER The mount path from Linux for guest machines
  • LINUX_GUEST_IMAGE_URL Linux WSL distribution .tar.gz archive
  • DISTRO_BASE Name for the Linux base template
  • DISTRO_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.

bash
# 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:

powershell
# 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:

bash
# 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:

/etc/wsl.conf
# 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.

PowerShell
# 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

Further customization

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 set
  • base-rustlang + Rust build dependencies
  • base-pyenv + Python dependencies
  • base-stablediffusion + Stable Diffusion packages

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


Exporting Linux templates

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:

PowerShell
$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.


Bootstrapping fresh from a Linux template

To create a new Linux guest from a template:

PowerShell
$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.

Footnotes

  1. Visit the Ubuntu cloud images file directory to find the latest release.

  2. Microsoft Learn: Advanced settings configuration in WSL

  3. Microsft Learn, ibid: The 8 second rule for configuration changes

  4. github.com/dotfiles: Your unofficial guide to Dotfiles

Ready to spark your next big big idea?
Join up for the occasional jolt of inspiration.
Made with ♡ in New York City
© 2025 Kitespark LLC.