WSL 2 and Visual Studio Code

Reading time:
5 minutes
Published:
Modified:
Tags:
windows
wsl-2

It was back in 2016 I formatted my laptop for the first time and swapped to Ubuntu. Since then I've been re-installing between Windows 10 and Ubuntu every few months. The past 8 months have been an exception and while I created a dual boot setup, I've started Windows 10 only a few hours in total and stayed on Ubuntu.

The reason I like Ubuntu is that it is fast, and I mean really fast. For example, in just a few seconds npm update is finished, the same goes for composer commands and docker containers are started instantly. As I said it's just an example because everything feels fast. Don't expect to break any speed records when trying development on Windows. Also, the way updates are handled, the snaps that are recently added. It is easy to work with. The reason I swap to Windows is when I want to do more than work, connect two monitors or need sporadically and application that doesn't run on Ubuntu. I have tried Windows 10 several times with WSL, Windows Subsystem for Linux. It's a good start but it didn't have a full Linux kernel implementation so a lot didn't work. And WSL is slow… Very slow.

And then, a few months ago, Microsoft announced WSL 2. It should be fast, have a full Linux kernel implementation and fixes all issues with WSL. Because of the full Linux kernel, all programs that run in Ubuntu will run its WSL 2 version. As curious as I am I thought I'm just going to try it. I can always wipe my disk and install Ubuntu again.

Getting started

There is a downside for trying it right now. You need Windows 10 build 18917 or higher. This means you have to subscribe to the fast ring or download a Windows Insider ISO. Once you have Windows 10 18917+ installed, we can start with WSL 2 itself.

Enable the ‘Virtual Machine Platform’ and WSL components

Open PowerShell as an Administrator and start the installation:

Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

This will make sure that both the Virtual Machine Platform and Windows Subsystem for Linux optional components are installed. After you've run these commands you'll need to restart your computer.

Set WSL 2 as your default architecture

To make WSL 2 your default architecture you can do so with this command:

wsl --set-default-version 2

This will make any new distro that you install be initialized as a WSL 2 distro.

Install a distro from the Microsoft Store

Search for your distro in the store. I've seen Ubuntu, SUSE, Debian, Alpine and Kali. There are probably more.

Migrate a distro to WSL 2

If you used WSL you need to migrate the distro to WSL 2. Check if there is still a distro on version 1:

wsl --list --verbose

And then migrate each distro to version 2:

wsl --set-version <Distro> 2

So for Ubuntu, this would be wsl --set-version Ubuntu 2.

And that's it. You now have WSL 2. Open a Ubuntu terminal by typing ubuntu in PowerShell or cmd. Set it up, add your ssh key, install PHP, Node and git, download a git repo, play around and enjoy the speed. You have a fast full functioning Ubuntu terminal.

But wait… there is more

Of course, there is more. The title mentions Visual Studio Code. The speed of WSL 2 impressed me a lot but actually using it with VS Code was amazing.

If you didn't install it yet, get Visual Studio Code and install it. Once you have it, install the Remote Development extension. It has currently the preview label but basically, this installs all extensions you need to get WSL 2 integrated with VS Code.

Once installed, on the left bottom you get a new green button. Click on it and select Remote-WSL: New Window. The first time you will do this it will setup WSL. Taken from the manual:

VS Code is installing a small server on the Linux side that the desktop VS Code will then talk to. That server will then install and host extensions in WSL so that they run in the context of the tools and frameworks installed in WSL. In other words, your language extensions will run against the tools and frameworks installed in WSL, not against what is installed on the Windows side, as it should for the proper development experience.

This is amazing. For example, if you need tools like nodejs, PHP or git, VS Code will use what is installed on the WSL distro. Besides the editor, you don't need anything anymore on Windows itself. Finally, all my Windows dev-tools installation nightmares are over and the maintenance mess is gone.

Want to see why I'm so excited about this? Check out this example. It's for an SSH connection, but it's about the same.

I forgot to mention that if you open a terminal, you go straight to the right path in the Ubuntu WSL instance.

Access localhost: from Windows

This is interesting:

Build 18945 Allow listening tcp sockets in WSL2 to be accessible from the host by using localhost:port Build 18970 Fix localhost port relay when server binds to localhost directly [GH 4353]

What this means is that if you bind your dev tools to localhost inside WSL 2 you can access it from windows by localhost:<port>. I tried this with Hugo and it binds to 127.0.0.1. That doesn't seem to work. But I have found a workaround:

sysctl -w net.ipv4.conf.all.route_localnet=1
iptables -t nat -I PREROUTING -p tcp -j DNAT --to-destination 127.0.0.1

Now if you start the Hugo server, it binds to 127.0.0.1:1313 and you can access it in your preferred Windows browser at http://localhost:1313/.

You might want to keep an eye on this page as it contains this WSL 2 hack and more.

What's next

It would be nice if I could get PhpStorm working the same way. However, I'm afraid it's not going to be that easy. Also trying out docker containers is on the top of my Todo list.