Getting started with WSL 2
Tags: wsl, windows, beginners, tutorial
Published: 2021-03-26 09:21:01

My life as an engineer has predominantly been one within the realms of Windows. Whilst some may shudder at the thought, I've always been happy working in this environment. Over the last couple of years, however, I've gradually been exposed to the world of Linux, predominantly through my use of [WSL](https://docs.microsoft.com/en-us/windows/wsl/). 
 
This year I've been co-running a weekly technical workshop with [Ben Selby](https://github.com/benmatselby) on a range of subjects. Last week I ran a workshop on my experiences with WSL, outlining what I've learnt along the way and how I try to get the most out of it.

This post marks the first of a small series around WSL I'd like to do off the back of that workshop.

---

## What is WSL?

WSL, or Windows Subsystem for Linux, is an optional feature on Windows that allows you to install a Linux distribution without any of the previous legwork you would have done previously, such as dual-booting your PC, or setting up a VM.

---

## Why WSL 2?

I originally started using WSL 1, and while I could work fairly comfortably with it, the nature of my work meant that I did have a couple of frustrating issues, namely around Docker and the way WSL [resolved the mounting of volumes](https://github.com/docker/for-win/issues/2151). 

WSL 2 was a major architectural change for WSL, introducing the use of a full Linux Kernel, increased file system performance and 100% system call compatibility. 

In my opinion, WSL 2 is far superior, and if you're new to WSL I'd skip straight past WSL 1. As always, there are [exceptions](https://docs.microsoft.com/en-us/windows/wsl/compare-versions#exceptions-for-using-wsl-1-rather-than-wsl-2) to bear in mind, but they're unlikely to be an issue for the majority.

---

## Pre-requisites

I'll get the boring stuff out of the way early. To install WSL 2, you're going to need to be running the following at the very least:

- **x64**: Windows version 1903 or higher, with Build 18362 or higher.
- **ARM64**: Windows version 2004 or higher, with Build 19041 or higher.

You can use `winver` to find this out :+1:

---

## Installation

Installing WSL is quick and simple; I'm using PowerShell (as admin) for the commands below:

**Step 1** - Enable WSL and virtual machine features

```powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

**Step 2** - Download the [linux kernel package](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)


**Step 3** - Set WSL 2 as your default (more on `wsl.exe` later)

```powershell
wsl --set-default-version 2
```


**Step 4** - [Choose your distro](https://aka.ms/wslstore)

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3qig5572axkhwjyb0dfp.png)

**Step 5** - Create your user account and password

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yyni87n84rb0hh7yjvs2.png)
 

**Step 6** - Confirm everything is up and running

```powershell
> wsl --list -v

  NAME                   STATE           VERSION
  docker-desktop-data    Running         2
* Ubuntu-18.04           Running         2
  docker-desktop         Running         2
```
---

## Making use of `wsl.exe`

As you may have gathered from the installation instructions, you can interact with WSL by using the `wsl` command. 

There are a [few different things](https://docs.microsoft.com/en-us/windows/wsl/reference) you can do with it, but here are the commands I've found most useful:

**Opening the default distro**

```powershell
> wsl --list -v

    NAME                   STATE           VERSION
    docker-desktop-data    Running         2
  * Ubuntu-18.04           Running         2
    docker-desktop         Running         2

> wsl
  ```

The `*` denotes the default distribution. If you enter `wsl` it opens the default shell, which in this case is `Ubuntu-18.04`.

If you do have multiple distros and you want to log in to a "non-default", you can add some more context to your command:

```powershell
> wsl --list -v

  NAME                   STATE           VERSION
  docker-desktop-data    Running         2
* Ubuntu-18.04           Running         2
  Debian                 Running         2
  docker-desktop         Running         2

> wsl -d Debian
```

**Changing the version of WSL for your distro**

```powershell
> wsl --set-version Ubuntu-18.04 1
> wsl --list -v

  NAME                   STATE           VERSION
  docker-desktop-data    Running         2
* Ubuntu-18.04           Running         1
  docker-desktop         Running         2
```
This is admittedly an odd example given my belief that most engineers will be best served by using WSL 2, but it's useful nonetheless. You can switch between versions with a single command, which can be handy if for whatever reason you have a version-specific issue you need a workaround for. For now, at least, [Microsoft has no plans to deprecate WSL 1](https://docs.microsoft.com/en-us/windows/wsl/wsl2-faq#what-will-happen-to-wsl-1--will-it-be-abandoned-), so it's worth having this in your locker.

**Importing and exporting distros**

```powershell
> wsl --export Ubuntu-18.04 C:\wsl-exports\ubuntu.tar
```

```powershell
> wsl --import Ubunthree-18.04 C:\my-distros\ubunthree C:\wsl-exports\ubuntu.tar
> wsl --list -v

  NAME                   STATE           VERSION
  docker-desktop-data    Running         2
* Ubuntu-18.04           Running         2
  docker-desktop         Running         2
  Ubunthree-18.04        Running         2
```

Once you install your distro of choice from the Microsoft Store you can't subsequently get that same distro again as it's now considered installed. 

You can, however, export your existing distro to a `.tar` file, then import it again under a different name, as the example above shows. I found this very useful when I was comparing the features of WSL 1 & 2, but you could do it for a multitude of other reasons, such as splitting your personal or work projects across distros or splitting by technical disciplines, such as front or backend development.

If you work with a team of engineers, it can also be useful to have a tarball of a "base" distro that has everything your team needs pre-baked into the distro.

---

## The snagging list

As great as WSL 2 is, there's a couple of hiccups that I've found along the way that I want to share in the hope that others avoid the hair pulling and excessive profanity I engaged in:

- Symantec Endpoint Protection played [havoc](https://github.com/microsoft/WSL/issues/4926#issuecomment-590829828) with my ability to perform apt package-management updates and upgrades. Fortunately, I don't use Symantec anymore and I'm not sure if they've patched out a fix to resolve it.

- Recently I came across an issue with my distro whereby I couldn't hit the internet at all. I was stumped, but thankfully [@coltenkrauter](https://github.com/coltenkrauter) created a [gist](https://gist.github.com/coltenkrauter/608cfe02319ce60facd76373249b8ca6#file-fix-wsl2-dns-resolution) that gave step by step instructions on how to solve it. :heart:

- The ability to convert your distro between WSL 1 & WSL 2 can be really useful but be warned that the larger it gets, the longer the conversion times will get. Conversion on a fresh distro is a matter of seconds, but when I've been using a distro for a protracted amount of time (I'm talking months here) with large numbers of cloned repos, you're going to be looking at hours.

---

## That's a wrap

This marks the end of part 1 of my **WSL while you work** series. Next up will be a post on how I use VS Code in conjunction with WSL for my day-to-day engineering.

---

## References

- [Installing WSL2](https://docs.microsoft.com/en-us/windows/wsl/install-win10)
- [WSL 1 vs WSL 2](https://docs.microsoft.com/en-us/windows/wsl/compare-versions)
- [WSL command reference](https://docs.microsoft.com/en-us/windows/wsl/reference)

## Credit

[Oskar Yildiz](https://unsplash.com/@oskaryil) for the photo :camera: