Install Fedora 37 or earlier on Windows Subsystem for Linux (WSL)
Tags: wsl, fedora, linux, windows
Published: 2020-07-13 10:40:32

Using Windows Subsystem for Linux (WSL), we have a choice of Linux distributions available in the Windows Store, such as Ubuntu, Kali, Debian, etc.

In addition to these, with WSL 2, installing custom distributions is fairly straightforward, even if they are not in the Windows Store:

- find a rootfs for the distro
- install with `wsl --import` in Windows Powershell or Command Prompt

Lately I rely on Fedora in WSL 2, and have been thoroughly pleased with that distribution. This article details the steps I use to get up and running with Fedora on WSL. By the way, if you prefer a nice out-of-box experience, take a look at the fine work by Whitewater Foundry with their [Fedora Remix for WSL](https://www.whitewaterfoundry.com/fedora-remix-for-wsl). But if you see "some assembly required" as an enticing invitation, read on.

> Already have a previous version of Fedora on WSL 2, and just want to upgrade to the latest? I [documented the steps involved in another article][fedora-upgrade]; feel free to take a look.

## Prerequisite: WSL 2

__Please note that these steps require WSL 2 (not version 1).__

> To run WSL 2, Windows version 1903 or higher is needed, with Build 18362 or higher. Most likely, you have a much later version than this already. To tell what version you are running, run `winver` in Powershell or CMD, or just type Win key and R (⊞-r) to open the Run dialog and then enter `winver`. Hopefully you will see something like "Version 21H2. OS Build 19044.1503". If on Windows 11, you needn't worry at all anyway, but the version should be something like "Version 21H2. OS Build 22000.1165".

To check if you are running WSL 2, try this command:

```bash
wsl --set-default-version 2
```

This will set the default version to WSL 2, or fail if you are still on the first version.

If it does neither and instead offers installation instructions, this may be your first time using WSL on this system.

Microsoft offers [helpful installation instructions](https://docs.microsoft.com/en-us/windows/wsl/install), including [step-by-step instructions on how to upgrade to WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install#upgrade-version-from-wsl-1-to-wsl-2).

In short, if you are comfortable installing another Linux distribution, running `wsl --install` will install the default latest Ubuntu, or you can pick from a list by using `wsl -l -o` then installing one with `wsl --install -d Debian` or, if not Debian, whichever distribution you would like.

If you are on an older version of Windows 10 or using WSL version 1, then the following Powershell command should get you to where you need (a reboot will likely be necessary).

```
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux,VirtualMachinePlatform -All
```

Most likely, the `wsl` command will then instruct you to install a new kernel, so proceed to [https://aka.ms/wsl2kernel](https://aka.ms/wsl2kernel) and follow the instructions there.

Again, see [Microsoft's instructions](https://docs.microsoft.com/en-us/windows/wsl/install) for a current and detailed version.

## Obtain a rootfs image of Fedora

We first need a rootfs (the base filesystem for the Linux distro in question, in this case Fedora). There a few ways to get this.

### Obtain rootfs from Fedora Container Base

The rootfs embedded in the [Fedora Container Base](https://koji.fedoraproject.org/koji/packageinfo?packageID=26387) project seems to work well, and is my preferred method, as it offers a lot of flexibility. I start with the most recent stable version of Fedora that auto-built successfully. If you want to be bleeding edge, you can download the latest Rawhide image that built successfully, but I am using the latest Fedora 37 for now. The "State" column indicates build success. Pick the latest with a green checkmark.

Find the right "xz" file for your platform (likely `x86_64`). Such as:

- [Fedora 37, built on October 29, 2022](https://kojipkgs.fedoraproject.org//packages/Fedora-Container-Base/37/20221029.n.0/images/Fedora-Container-Base-37-20221029.n.0.x86_64.tar.xz).
- [Fedora 36, built on October 29, 2022](https://kojipkgs.fedoraproject.org//work/tasks/4402/93554402/Fedora-Container-Base-36-20221029.0.x86_64.tar.xz).
- [Fedora 35 built on October 29, 2022](https://kojipkgs.fedoraproject.org//packages/Fedora-Container-Base/35/20221029.0/images/Fedora-Container-Base-35-20221029.0.x86_64.tar.xz).


Unpack the `Fedora-Container-Base-*.tar.xz` file in your preferred manner. You might try [7-zip](https://www.7-zip.org/download.html) for this, extracting the .tar file, then extracting the contents of the .tar file. This, however, _is not_ your rootfs. Further work is needed.

Once unpacked you will see a folder with a long hexadecimal name. Within that folder, there should be a `layer.tar` file. **This is your rootfs.** Copy the `layer.tar` file to a logical location, such as your Downloads folder. You may even want to rename it to something like `fedora-33-rootfs.tar`.

### Alternative: download rootfs from docker-brew-fedora project

The [docker-brew-fedora](https://github.com/fedora-cloud/docker-brew-fedora) project imports "the official Fedora Docker Base Images built in [Fedora Koji](http://koji.fedoraproject.org/koji/) (Fedora's Build System) so that they may be submitted to the [official-images](https://github.com/docker-library/official-images) repository for the [Docker Hub](https://hub.docker.com/)."

To download, first [pick your desired Fedora version from the active branches](https://github.com/fedora-cloud/docker-brew-fedora/branches/active). For example, you might choose [Fedora 37](https://github.com/fedora-cloud/docker-brew-fedora/tree/37/x86_64) and there find a file with a name like `fedora-37-x86_64.tar.xz`. Or use [Fedora 36](https://github.com/fedora-cloud/docker-brew-fedora/tree/36/x86_64) and look for `fedora-36-x86_64.tar.xz`. Or go for [Fedora 35](https://github.com/fedora-cloud/docker-brew-fedora/tree/35/x86_64) and locate `fedora-35-x86_64.tar.xz`. Download that file.

Unpack the `fedora-3?-x86_64.tar.xz` file in your preferred manner. You might try [7-zip](https://www.7-zip.org/download.html) for this, extracting the .tar file, then, if desired, renaming it to something like `fedora-36-rootfs.tar`.

### Another rootfs alternative: use docker or podman and export

While this requires an extra tool, if you already have [docker](https://docs.docker.com/get-docker/) or [podman](https://podman.io/getting-started/) available, then you can pull the Fedora image of your choosing and export the rootfs. In the following, if you have a Linux distro with podman available, you can substitute `podman` in place of `docker`.

```
docker run --name fedora37 fedora:37
docker export -o fedora-37-rootfs.tar fedora37
```

First we create the container, name it "fedora37", then export the rootfs as "fedora-37-rootfs.tar". Afterward, you can certainly `docker rm fedora37` to clean up.

You may be interested in my articles for [configuring podman on WSL](https://dev.to/bowmanjd/using-podman-on-windows-subsystem-for-linux-wsl-58ji), or [setting up Docker on WSL](https://dev.to/bowmanjd/install-docker-on-windows-wsl-without-docker-desktop-34m9).

## Make a folder for your WSL distro.

Once we have the rootfs, we can prepare to import it.

I like to use `wsl` in my home directory, so in this case I create that folder and a `fedora` folder within it. In Powershell, that's:

```powershell
mkdir $HOME\wsl\fedora
```

## Install a new WSL Fedora distro

In Powershell, assuming you want to name the distro "fedora" and the folder is \$HOME\wsl\fedora and the rootfs is in Downloads, named "fedora-37-rootfs.tar":

```powershell
wsl --import fedora $HOME\wsl\fedora $HOME\Downloads\fedora-37-rootfs.tar
```

## View installed distros

If this is the only WSL distro you now have, executing `wsl -l` should look something like this:

```
PS C:\Users\me> wsl -l
Windows Subsystem for Linux Distributions:
fedora (Default)
```

## Launch Fedora as root

```powershell
wsl -d fedora
```

Or, if Fedora is the default, simply `wsl` should result in a BASH prompt.

If you have multiple distros installed, and want Fedora to be set as the default, something like this should work:

```powershell
wsl -s fedora
```

## Ensure DNS is functioning (skip this section if network functionality is good)

DNS in WSL is interesting. By default, WSL will set the DNS server automatically, dynamically configuring `/etc/resolv.conf`. If your dns is resolving fine (does `sudo dnf upgrade` work for you?) then you can skip to the next section. It seems that it just works for most people.

For me, however, the dynamic `/etc/resolv.conf` has not worked consistently. I need to turn it off and configure `resolv.conf` manually.

Conveniently, WSL provides [a means in `/etc/wsl.conf` to set some configuration settings](https://docs.microsoft.com/en-us/windows/wsl/wsl-config#configure-per-distro-launch-settings-with-wslconf) specific to WSL.

In order for DNS to work, we will create our own resolv.conf, but first we create a new wsl.conf file and disable auto-generation of resolv.conf:

```bash
echo -e "[network]\ngenerateResolvConf = false" > /etc/wsl.conf
```

Now exit WSL, then terminate it with

```powershell
wsl -t fedora
```

Then enter it again with

```powershell
wsl -d fedora
```

Now we can persist our custom DNS configuration. First, `unlink /etc/resolv.conf`. This covers cases in which `/etc/resolv.conf` is linked to systemd-resolved or resolvconf generated files. Then create a new `/etc/resolv.conf` with [the nameserver(s) of your choice](https://www.dnsperf.com/#!dns-resolvers):

```bash
unlink /etc/resolv.conf
echo nameserver 1.1.1.1 > /etc/resolv.conf
```

Why not test network settings now with a system upgrade:

```bash
dnf upgrade
```

If repositories are synced, you have success!

## Missing the `mount` command?

If, at first entry to your new Fedora instance, you are greeted with `An error occurred mounting one of your file systems`, then that is a sign you are missing the `util-linux` package, which includes `mount` as well as other essential commands. Depending on the rootfs you installed, you may not receive any error, in which case you can proceed to the next section.

But if you do need mount, install `util-linux` (or, if you are going minimalist, just install `util-linux-core`).

```bash
dnf install -y util-linux
```

Then exit, and terminate your fedora instance (this, in effect, causes a restart):

```powershell
wsl -t fedora
```

## Launch Fedora as an unprivileged user

Just sayin': `root` should never be your default user. Let's create a normal user.

We are going to need `passwd` for this, and we might as well get the cracklib dicts for password checking, too. Install both, once you have launched Fedora:

```bash
dnf install -y passwd cracklib-dicts
```

Now, create a new user; while we are at it, let's add them to the `wheel` group so the user can `sudo` (don't forget to replace "myusername" with something that makes sense for you):

```bash
useradd -G wheel myusername
```

Then create a password for that user:

```bash
passwd myusername
```

Now, exit WSL or launch a new Powershell window, then re-launch WSL with the new username:

```powershell
wsl -d fedora -u myusername
```

Success?

```
$ whoami
myusername
```

Does `sudo` work?

```bash
sudo cat /etc/shadow
```

If you see the list of users, including, toward the bottom, the one you recently added, then all is well!

## Set the default user

It would be nice to enter your Fedora instance as the user you just created, rather than as root.

To enable this, assuming you have Windows build 18980 or later: simply add a [user section to `/etc/wsl.conf`](https://docs.microsoft.com/en-us/windows/wsl/wsl-config#user).

Something like this will work well if you do not already have that file, or a `[user]` section in it:

```bash
printf "\n[user]\ndefault = myusername\n" | sudo tee -a /etc/wsl.conf
```

Then exit, and terminate your fedora instance, so that it starts fresh next time.

```powershell
wsl -t fedora
```

Launch WSL again, without specifying a user, and you should be that user, not root.

If that succeeded, then proceed to the next section.

But if on a version of Windows before build 18980, then you will instead need to edit the registry to set a default user.

In Fedora, the user you created likely has a user id of 1000, but you can check with `id -u`. Remember that number.

Back in Powershell you can set the default user by editing the Windows registry, changing "fedora" and "1000" to what you named your WSL distro and the user id, respectively:

```powershell
Get-ItemProperty Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\*\ DistributionName | Where-Object -Property DistributionName -eq fedora  | Set-ItemProperty -Name DefaultUid -Value 1000
```


## Fine tuning

If you do container work, especially in userspace, you will likely want to reinstall shadow-utils, in order to fix sticky bits that weren't set properly in the rootfs:

```bash
sudo dnf reinstall -y shadow-utils
```

If you like to ping servers to see if they are up, then these two steps may be necessary:

```sh
sudo dnf install -y procps-ng iputils
sudo sysctl -w net.ipv4.ping_group_range="0 2000"
```

The second one allows group IDs all the through 2000 to be able to ping. You can check group IDs with `getent group` or see your primary group ID with `id -g` and make sure it is included in the range above.

To make the above permanent, however, it is necessary to create or alter the `$HOME\.wslconfig` file **in Windows, not Linux**. Placing the following in that file will allow ping to work even after restarts:

```ini
[wsl2]
kernelCommandLine = sysctl.net.ipv4.ping_group_range=\"0 2000\"
```

You may also find other commands you are used to are missing from the sparse rootfs we installed. You may want to install `iproute`, `findutils`, `ncurses`, and others, like so:

```bash
sudo dnf -y install iproute findutils ncurses
```

While the included `vi` is a useful text editor, you will likely want one that is either more robust or has a user interface that suits you. Good options include `vim`, `micro`, or `nano`. Pick one and install it with something like:

```bash
sudo dnf install -y micro
```

From here, you can proceed to install packages, edit configurations, and customize your new distro to your heart's content!

## A few good man pages

You want the docs? You can't _handle_ the docs!

But if you can handle them, and can handle the extra storage space they will occupy, then you likely want man pages. Thanks to [Martin Hinze](https://dev.to/martinhinze) for his good suggestions on how best to add man page functionality. This is an enhancement, rather than baked in, because we obtained a slimmed-down rootfs earlier.

First, ensure the nodocs option is not set in `/etc/dnf/dnf.conf`. You may edit out the `tsflags=nodocs` line yourself, or use the following:

```bash
grep -v nodocs /etc/dnf/dnf.conf | sudo tee /etc/dnf/dnf.conf
```

Then install `man` and `man-pages`:

```bash
sudo dnf install -y man man-pages
```

This will ensure you get man pages on every future `dnf install`; however, to add them in retroactively, you will want to `dnf reinstall` any package for which you want man pages. For instance, `man dnf` will yield nothing now. But try it again after `sudo dnf reinstall -y dnf` and you should have good results.

To reinstall _all_ installed packages, try the following:

```bash
for pkg in $(dnf repoquery --installed --qf "%{name}"); do sudo dnf reinstall -qy $pkg; done
```

## Don't repeat yourself

Once you have a pristine base system the way you want it, why not export a tarball that you can import later. I mean, I am honored if you want to read this article again and follow it step by step. But if you want life to be a little easier, you might try the following.

First, clean up downloaded packages, etc. within Fedora:

```bash
sudo dnf clean all
```

Then, exit WSL and export the whole installation to a tarball:

```powershell
wsl --export fedora $HOME\Downloads\fedora-wsl.tar
```

You may want a different folder than `Downloads`; specify the location you desire.

Depending on what packages you installed, it may be as small as a quarter GB. You could gzip it if you want the storage size to be even smaller. Next time you want to start fresh, you can do something like this:

```powershell
mkdir $HOME\wsl\freshfedora
wsl --import freshfedora $HOME\wsl\freshfedora $HOME\Downloads\fedora-wsl.tar
```

## Keep upgrading

Even if you have a prerelease, there should be no need to reinstall. [Just keep upgrading](https://fedoraproject.org/wiki/Upgrading_from_pre-release_to_final#Performing_the_upgrade); the process is pretty seamless:

```bash
sudo dnf upgrade
```

For instance, if you decided to use Fedora 37 (you adventurer, you!), upgrade as often as you like with the above command, and you will eventually (by November of 2022, presumably) be at release.

## Interested in further tinkering with WSL 2?

Other articles I have written on WSL:

- [Using podman instead of Docker](https://dev.to/bowmanjd/using-podman-on-windows-subsystem-for-linux-wsl-58ji)
- [Install Docker without Docker Desktop](https://dev.to/bowmanjd/install-docker-on-windows-wsl-without-docker-desktop-34m9)
- [You Probably Don't Need systemd on WSL](https://dev.to/bowmanjd/you-probably-don-t-need-systemd-on-wsl-windows-subsystem-for-linux-49gn)
- [How to Upgrade Fedora In Place on WSL][fedora-upgrade]

[fedora-upgrade]: https://dev.to/bowmanjd/how-to-upgrade-fedora-in-place-on-windows-subsystem-for-linux-wsl-oh3