Lukasz Stafiniak

How to update or install a new Linux distribution on WSL

It’s easiest if the distribution is available in the Microsoft Store: How to install Linux on Windows with WSL Since it will help me debug opam-repository distributions, let’s start by installing some of MS Store distros.

PS C:\Users\lukst> wsl --list --online
The following is a list of valid distributions that can be installed.
Install using 'wsl --install -d <Distro>'.

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_7_9                        Oracle Linux 7.9
OracleLinux_8_7                        Oracle Linux 8.7
OracleLinux_9_1                        Oracle Linux 9.1
openSUSE-Leap-15.5                     openSUSE Leap 15.5
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
SUSE-Linux-Enterprise-15-SP5           SUSE Linux Enterprise 15 SP5
openSUSE-Tumbleweed                    openSUSE Tumbleweed
PS C:\Users\lukst> wsl --install -d Debian
Installing: Debian GNU/Linux
Debian GNU/Linux has been installed.
Launching Debian GNU/Linux...
PS C:\Users\lukst>

In my current setup, this failed to mount the Windows disk:

[17385.384063] init: (1) ERROR: MountPlan9WithRetry:285: mount drvfs on /mnt/c (cache=mmap,noatime,msize=262144,trans=virtio,aname=drvfs;path=C:\;uid=0;gid=0;symlinkroot=/mnt/
[17385.384064] ) failed: 16

Googling suggests the mounting should work when the distro is selected as default. It is also important to wsl --shutdown, otherwise the mounting problem doesn’t get fixed, and I cannot connect to the distro from VS Code.

P.S. Maybe, wsl --terminate -d Debian would suffice. Selecting as default does not seem to be needed. Even when code . does not start VS Code, opening a new VS Code window and selecting “Connect to…” and then “Connect to WSL using distro…” works.

For VSCode, WSL tips mentions installing wget and ca-certificates is also required. Here I install a different distribution:

PS C:\Users\lukst> wsl --unregister Ubuntu
PS C:\Users\lukst> wsl --install -d OracleLinux_9_1
PS C:\Users\lukst> wsl -s OracleLinux_9_1
PS C:\Users\lukst> wsl --list --all
Windows Subsystem for Linux Distributions:
OracleLinux_9_1 (Default)
PS C:\Users\lukst> wsl
$ sudo yum install ca-certificates
PS C:\Users\lukst> wsl --shutdown
PS C:\Users\lukst> wsl

Now, $ code . works.

OracleLinux does not have the GitHub CLI in the repository, I used this tutorial to install it.

I had Ubuntu-22.10 installed. It is past its shell life, therefore I couldn’t update it from within. Otherwise I could do:

$ sudo apt update & sudo apt upgrade
$ sudo emacs -nw /etc/update-manager/release-upgrades
# Change [DEFAULT] to [normal]
$ sudo apt remove snapd
$ sudo do-release-upgrade
Checking for a new Ubuntu release
Your Ubuntu release is not supported anymore.

The official tutorial to manually install distributions: Import any Linux distribution to use with WSL. This introduction is more to the point.

After wasting some time on other approaches, I downloaded Alpine from here, unpacked .tar.gz -> .tar via Git bash, and installed:

lukst@lukstafi-legion MINGW64 ~
$ gzip -d Downloads/alpine-minirootfs-3.18.4-x86_64.tar.gz

(Turns out the unpacking step is actually redundant, you can just use .tar.gz directly below.)

PS C:\Users\lukst> mkdir WSL\Alpine
PS C:\Users\lukst> wsl --import Alpine .\WSL\Alpine .\Downloads\alpine-minirootfs-3.18.4-x86_64.tar
PS C:\Users\lukst> wsl -s Alpine
PS C:\Users\lukst> wsl --shutdown
PS C:\Users\lukst> wsl

Now I download Archlinux from here and:

PS C:\Users\lukst> wsl --shutdown
PS C:\Users\lukst> mkdir WSL\Archlinux
PS C:\Users\lukst> wsl --import Archlinux .\WSL\Archlinux .\Downloads\base-20231029.0.188123.tar
PS C:\Users\lukst> wsl -s Archlinux
PS C:\Users\lukst> wsl

Now I add my user – this is not automated as it is with distros packaged for WSL. I also install packages, needed sooner or later.

# useradd -m -U myusername
# passwd myusername
# groupadd sudo
# usermod -aG sudo myuser
# pacman -Sy sudo git vi wget ca-certificates
# visudo
# # uncomment the line staritng with: # %sudo
# (echo [user]; echo default=lukstafi) >& /etc/wsl.conf
# exit
PS C:\Users\lukst> wsl --terminate Archlinux
PS C:\Users\lukst> wsl

Now let’s install GitHub CLI:

$ cd ~
$ export VERSION=`curl  "" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/' | cut -c2-`
$ wget${VERSION}/gh_${VERSION}_linux_amd64.tar.gz
$ tar xvf gh_${VERSION}_linux_amd64.tar.gz
$ sudo cp gh_${VERSION}_linux_amd64/bin/gh /usr/local/bin/

Let’s come back to Alpine and add the user.

PS C:\Users\lukst> wsl -d Alpine
# apk add adduser
# sudo adduser -g "My User" myuser
# apk add curl wget ca-certificates sudo
# addgroup sudo
# adduser lukstafi sudo
# visudo
# # uncomment the line staritng with: # %sudo
# (echo [user]; echo default=lukstafi) >& /etc/wsl.conf
# exit
PS C:\Users\lukst> wsl --terminate Alpine
PS C:\Users\lukst> wsl -d Alpine

Some more distro sources

I downloaded Debian Trixie i.e. 13 from here. Then: wsl --import Debian_Trixie .\WSL\debian_trixie .\Downloads\debian-trixie-rootfs.tar.xz

Unfortunately this way of installing Trixie gives a poor terminal experience. Also, opam cannot infer the os-version.

There is a whole project dedicated to NixOS on WSL, I downloaded nixos-wsl.tar.gz, then (this tutorial / configuration was helpful):

> wsl --import NixOS .\WSL\NixOS\ .\Downloads\nixos-wsl.tar.gz --version 2
> wsl -d NixOS
$ sudo nix-channel --add nixos

Installing Linux Mint for WSL2 is very easy, because SileshN’s project has its own Windows installer (archived together with the rootfs.tar.gz image). Then just: wsl -d Mint, it will interactively setup a new user. But the installer will not let you install multiple versions of Mint, so to install another parallel version you can download an older release, unpack it, and use wsl --import as above.

Installing FreeBSD (USB-only NomadBSD or FreeBSD on the disk) via a USB stick

I followed the installation instructions on Then I needed to disable Secure Boot in BIOS. You can get to BIOS settings by maybe pressing F2 on startup, or via Windows / Settings / Windows Update / Advanced Options / Recovery / Advanced startup: Restart now. Then I needed to disable auto-detection of graphics in NomadBSD: press 7 on startup for settings, then 6, (then 7 for verbose logging,) then 1, then 1. If the computer turns off at this moment, repeat this again (the settings are not saved).

The default shell of NomadBSD was hanging for me, fortunately entering bash resolved this!

NomadBSD was not really working for me, so I decided to install FreeBSD proper. Following instructions, I downloaded Win32 Disk Imager, a memstick image from BSD ISO Images. I freed up some disk space in Windows Disk Manager, stareted the install. I chose UFS. I installed ports. I tried to install WiFi but failed, so I picked the LAN connection. Adding the user does not suport sudo, so I logged in as root, pkg install sudo, pw group add sudo, pw group mod sudo -m lukstafi, pkg install vim – this also installs/enables visudo.

Now to install opam, I did cd /usr/ports/devel/ocaml-opam; sudo make install – don’t do this! Using both ports and packages can potentially mess up things. (It’s possible to Build port but install dependencies with pkg. Installing everything from source takes ~ a day?) In the end, I gave up and run sudo pkg install ocaml-opam. Then I faced problems with X11 and re-installed everything.

Next, setting up a GUI Window Manager, on top of either X11 or Wayland. I tried lots of things but nothing worked. TO BE CONTINUED?

Package managers

Packages to install:

To install them on an unsupported Ubuntu version:

$ sudo sed -i -e 's/|' /etc/apt/sources.list
$ sudo apt-get update
nix-shell -p gcc
nix-shell -p gnumake
nix-shell -p patch
nix-shell -p bubblewrap
nix-shell -p diffutils
nix-shell -p rsync
nix-shell -p curl
nix-shell -p wget
nix-shell -p git
nix-shell -p cacert
nix-shell -p bash
nix-shell -p unzip