Here's an easy method which allows you to install multiple instances of any Linux Distro in any location under WSL2.
** Click on each heading to reveal instructions **
If you HAVEN'T installed WSL2 prior to this, open up a Powershell terminal and execute the following commands:
PS C:\> Enable-WindowsOptionalFeature -Online -FeatureName 'Containers' -All
PS C:\> Enable-WindowsOptionalFeature -Online -FeatureName 'Microsoft-Hyper-V' -All
PS C:\> Enable-WindowsOptionalFeature -Online -FeatureName 'VirtualMachinePlatform' -All
PS C:\> Enable-WindowsOptionalFeature -Online -FeatureName 'Microsoft-Windows-Subsystem-Linux' -All
The first thing you need to do is download a linux distro. This is a list of all distros released by Mocrosoft specifically for WSL2:
- Ubuntu
- Ubuntu 24.04
- Ubuntu 22.04 LTS
- Ubuntu 20.04
- Ubuntu 20.04 ARM
- Ubuntu 18.04
- Ubuntu 18.04 ARM
- Ubuntu 16.04
- Debian GNU/Linux
- Kali Linux (Win-Kex Install Docs)
- SUSE Linux Enterprise Server 12
- SUSE Linux Enterprise Server 15 SP2
- SUSE Linux Enterprise Server 15 SP3
- openSUSE Tumbleweed
- openSUSE Leap 15.3
- openSUSE Leap 15.2
- Oracle Linux 8.5
- Oracle Linux 7.9
- Fedora Remix for WSL
(And if you're not already using it, install Windows Terminal from the Windows Store also - you won't regret it)
So, let's assume for a moment that your C: drive is dangerously low on space and you need to choose another location to install WSL2. Using Windows Explorer, grab the Linux distro you just downloaded from your downloads directory and copy it to wherever you're going to install it. For the purposes of this guide, I'm going to assume that you've downloaded Ubuntu 22.04 LTS and you're going to install into E:\WSL.
Open Windows Terminal to a Powershell prompt and execute the following commands to create your install location:
PS C:\> E:
PS E:\> mkdir WSL
Now, the first thing you need to do is rename the archive of the distro you downloaded so that it has a .zip
extension:
PS E:\> cd WSL
PS E:\WSL> mv Ubuntu2204-221101.AppxBundle Ubuntu-22.04.zip
Then, using Windows Explorer, double click on the distro archive, then select and extract the _x64.appx
file as shown below:
Once you've extracted the installer, you don't actually need the archive you pulled it from any longer. You can delete it or stick it in your own file archives if you like - and you're going to need to change the extension on that .appx
file as well (either using Windows Explorer or Powershell - up to you)
PS E:\WSL> rm Ubuntu-22.04.zip
PS E:\WSL> mv Ubuntu_2204.1.7.0_x64.appx Ubuntu-22.04.zip
PS E:\WSL> Expand-Archive -Path Ubuntu-22.04.zip -DestinationPath E:\WSL\Ubuntu
The end result of which will be:
Then all you need to do is execute the ubuntu.exe
file to install your first instance:
PS E:\WSL> cd Ubuntu
PS E:\WSL\Ubuntu> .\ubuntu.exe
Now let's create your BASE INSTANCE
.
Open either a simple Command Prompt or a Powershell Prompt and let's take care of a little housekeeping.
First, get a list of all WSL instances currently running on your machine:
PS E:\WSL> wsl -l -v
It should look something like this:
NAME STATE VERSION
* Ubuntu Running 2
(* Each instance will be named after its parent folder ... more on this later)
Hopefully you've installed Windows Terminal from the Windows Store - if not, you can open a new terminal window for any WSL instance using this command:
wsl -d <instanceName>
PS E:\WSL> wsl -d Ubuntu
This first step is not necessarily based on best practices, but I've always found it to be useful. Skip this step if you want to:
user@WSL: /$ sudo passwd root
Next you want to make sure you've got the latest version of everything installed:
user@WSL: /$ sudo apt update && sudo apt upgrade -y
If you've installed an Ubuntu LTS release, you're also going to want to make sure you've got the latest kernel updates:
user@WSL: /$ sudo do-release-upgrade
In any case, you'll want to make sure to clean up after yourself:
user@WSL: /$ sudo apt autoremove -y && sudo apt autoclean -y
... and if kernel updates were installed, you'll want to reboot:
user@WSL: /$ sudo reboot
WSL2 configuration happens in 2 files:
- .wslconfig - is stored in your %USERPROFILE% directory in Windows and applies to ALL WSL INSTANCES
- /etc/wsl.conf - applies only to the instance it is part of
First, let's take care of your instance configuration file - /etc/wsl.conf:
(copy and paste everything below onto your linux command line)
user@WSL: /$ sudo tee /etc/wsl.conf > /dev/null <<EOF
# Automatically mount Windows drives when distribution is launched
[automount]
# Set whether to automount fixed drives with drvfs under the "root" dir specified below
enabled = true
# Set the directory where fixed drives will be automatically mounted
root = /mnt
# drvfs-specific options for mounted drives
options = "metadata,uid=1000,gid=1000,umask=22,fmask=11,case=off"
# Set whether to process /etc/fstab on boot
mountFsTab = true
# Network host settings
[network]
# Set hostname
hostname = wsl
# Set whether to automatically generate /etc/hosts file
generateHosts = true
# Set whether to automatically generate /etc/resolv.conf file
generateResolvConf = true
# Interop settings only available in build 17713 and later
[interop]
# Set whether to support interop processes like launching windows apps from linux
enabled = true
# Set whether to append Windows path to Linux path
appendWindowsPath = true
# User settings only available in build 18980 and later
[user]
# Set the default user when launching a distro
default = ragdata
# Boot settings only available on Windows 11 and Server 2022
[boot]
# Set whether to enable systemd
systemd = true
# Set a command to run when a new WSL instance launches
#command = service docker start
EOF
Next, let's take care of your global configuration file - .wslconfig
[wsl2]
# Limit VM memory use default - smallest of 50% of total or 8GB
memory = 4GB
# Limit VM to 2 virtual processors default - The number of processors on Windows
processors = 2
# Set localhost forwarding default - true
localhostForwarding = true
# Specify a custom kernel to use with your installed distros default - blank
# kernel = C:\\temp\\myCustomKernel
# Set additional kernel parameters default - blank
# kernelCommandLine = vsyscall=emulate
# Set available swap space default - 25% of memory rounded up
swap = 8GB
# Set swapfile location default - %USERPROFILE%\AppData\Local\Temp\swap.vhdx
swapfile = C:\\temp\\wsl-swap.vhdx
# Enable Windows to reclaim unused memory allocated to a WSL VM default - true
pageReporting = true
# Enable support for GUI applications (WSLg) - Windows 11 only default - true
guiApplications = true
# Enable debug console - Windows 11 only default - true
debugConsole = false
# Enable nested virtualization - Windows 11 only default - true
nestedVirtualization = true
# Set VM idle timeout - Windows 11 only default - 60000
vmIdleTimeout = 60000
Entries with a PATH
value must be Windows paths with escaped backslashes, eg: C:\\Dir\\file
Entries with a SIZE
value must be a size followed by a unit, eg: 8GB
or 512MB
Create your .wslconfig
file under C:\Users\<username>\.wslconfig
I find it useful to be able to mount certain Windows directories under certain Linux directories depending upon the role intended for a WSL2 instance. For example, if an instance is to be a docker host, you may want to mount a specific location for docker volumes and other data under certain directories:
user@WSL: /$ sudo tee /etc/fstab > /dev/null <<EOF
# UNCONFIGURED FSTAB FOR BASE SYSTEM
LABEL=cloudimg-rootfs / ext4 defaults 0 0
D:\ /mnt/d drvfs metadata,uid=1000,gid=1000,umask=22,fmask=11,case=off 0 0
/mnt/d/Projects /home/ragdata/projects drvfs metadata,uid=1000,gid=1000,umask=22,fmask=11,case=off,bind 0 0
EOF
user@WSL: /$ mkdir -p /home/ragdata/projects
user@WSL: /$ sudo reboot
NOTE: If you do mount a folder as demonstrated above, make sure that you create the destination folder before you reboot, or FsTab will throw an error when it tries to mount the directory and can't find it.
NOTE: You will only be able to install GUI support for Ubuntu on WSL2 if you can find your graphics card listed HERE.
I usually skip this step because it inflates the size of the.vhdx
file for an instance quite considerably (bloat).
- Install
gcc
if you haven't already:
user@WSL: /$ sudo apt install gcc -y
- Install the CUDA keyring:
user@WSL: /$ sudo wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.0-1_all.deb
user@WSL: /$ sudo dpkg -i cuda-keyring_1.0-1_all.deb
- Update & Install CUDA
user@WSL: /$ sudo apt update
user@WSL: /$ sudo apt install cuda -y
- Install basic X11 applications
user@WSL: /$ sudo apt install x11-apps -y
If you have any SSH keys that will be required by your WSL2 instances, now would be a good time to include them (eg: SSH key for GitHub)
For the purposes of this guide, I'll assume that you've already got an SSH Key that you use to authenticate with GitHub set up and working. All that needs to happen is that you set up a .ssh
folder under your WSL directory that you can copy your existing key into . So, using Powershell:
PS E:\WSL> mkdir .ssh
PS E:\WSL> cp ~\.ssh\key_name .ssh\key_name
PS E:\WSL> cp ~\.ssh\key_name.pub .ssh\key_name.pub
PS E:\WSL> $text = "Host github.com"
PS E:\WSL> $text > .ssh\config
PS E:\WSL> $text = " IdentityFile ~/.ssh/key_name"
PS E:\WSL> $text >> .ssh\config
Then the easiest way to copy your .ssh
folder to wherever it needs to be is like so:
PS E:\WSL> cp -R .ssh \\wsl$\Ubuntu\home\ragdata
Then switch to your WSL terminal window and take care of permissions:
user@WSL: ~$ sudo chown -R ragdata:ragdata .ssh
user@WSL: ~$ chmod 0600 .ssh\*
user@WSL: ~$ chmod 0644 .ssh\*.pub config
And add a couple of lines to .bashrc
to make the key available to the ssh-agent:
user@WSL: ~$ echo "eval $(ssh-agent) &> /dev/null" >> .bashrc
user@WSL: ~$ echo "ssh-add ~/.ssh/key_name &> /dev/null" >> .bashrc
user@WSL: ~$ . ~/.bashrc
The easiest way to install docker on WSL is to simply install Docker Desktop for Windows 11 and tick the boxes under settings for which WSL2 instance you want to have access to it. However, for the purposes of this guide, I'm going to assume that you intend to run docker on your Linux instances independently of Docker Desktop (because you might want to host a swarm)
- Install prerequisites:
user@WSL: ~$ sudo apt install ca-certificates curl gnupg2 lsb-release -y
- Add Docker's official GPG key:
user@WSL: ~$ sudo mkdir -p /etc/apt/keyrings
user@WSL: ~$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- Use the following command to set up the Docker repository:
user@WSL: ~$ echo \
> "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
> $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /de>v/null
- Install Docker Engine
user@WSL: ~$ sudo apt update
user@WSL: ~$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
- Create Additional Non-Root User
Because docker needs to grant some hefty privileges to a non-root user, it's a good idea to set up a user specifically for this:
user@WSL: ~$ sudo adduser dockeruser
Then grant that user sudo privileges:
user@WSL: ~$ sudo usermod -aG sudo dockeruser
Finally, add this user to the docker
group:
user@WSL: ~$ sudo usermod -aG docker dockeruser
- Create a config file for the
dockerd
daemon:
user@WSL: ~$ sudo mkdir -p /etc/docker
user@WSL: ~$ sudo tee /etc/docker/daemon.json > /dev/null <<EOF
{
"hosts": ["tcp://0.0.0.0:"],
"tls": false
}
EOF
Then, you can launch dockerd
directly using the following command:
user@WSL: ~$ sudo dockerd
and stop it with CTRL-C
If you want to launch dockerd
in the background, use:
user@WSL: ~$ sudo dockerd &
and stop it with:
user@WSL: ~$ sudo pkill dockerd
OR you can do it the RIGHT way and launch it via systemd:
user@WSL: ~$ sudo service docker start
and verify that it's working with:
user@WSL: ~$ sudo docker run hello-world
- Stop all instances of WSL
PS C:\> wsl --shutdown
-
Open Registry Editor (regedit) and go to: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss
- Each subfolder on Lxss represents a WSL instance
-
Locate and rename your distro by editing the
DistributionName
key in the appropriate subfolder - click OK -
Open Powershell as Admin and restart WSL with the command:
PS C:\> Get-Service LxssManager | Restart-Service