Using Remote Containers in WSL 2

July 1, 2020 by Brigit Murtaugh, @BrigitMurtaugh

Leveraging the power of Docker containers and the Windows Subsystem for Linux 2 (WSL 2), you can preserve your Windows environment by developing your applications in the sandboxed familiarity of a container in a deeply integrated Linux kernel.

May brought us a couple of exciting announcements in the world of virtualization: the Windows 10 May 2020 update added WSL 2 as a feature out-of-the-box, and Docker Desktop Stable 2.3.0.2 went GA with WSL 2 backend support.

In earlier blog posts, we've explored how to use Docker in WSL 2. The first requirement was to install Windows Insiders, as WSL 2 support was not yet part of stable Windows releases, and the next was to install a Tech Preview of Docker WSL 2. Now, both Windows WSL 2 and Docker support are in stable GA releases!

In this post, we'll take a look at how both of these tools work, and how you can leverage them in Visual Studio Code to productively use remote containers in WSL 2.

New era of virtualization

Both WSL 2 and the latest version of Docker Desktop change how virtualization works.

WSL 2

As discussed in a prior post, WSL 2 takes a new approach on the Windows Subsystem for Linux by using a real Linux kernel inside a lightweight virtual machine (VM). It has been optimized to feel seamless and deeply integrated into your Windows environment so that you have fast boot times, a small resource footprint, and no VM configuration or management requirements whatsoever.

System calls allow you to perform functions such as accessing files, requesting memory, and creating processes. Since WSL 2 includes a complete Linux kernel, it has full system call capacity, meaning your favorite apps such as Docker will work fully and reliably.

Docker

In WSL 1, due to fundamental differences between Windows and Linux, the Docker Engine couldn't run directly inside WSL, and the Docker team developed an alternative solution using Hyper-V VMs and LinuxKit. However, since WSL 2 now has full system call capacity, Docker can fully run in WSL 2, which prompted more investment from the Docker team.

The new May 2020 version of Docker Desktop can build containers much faster and consume fewer resources as it leverages WSL 2's dynamic memory allocation. It can take less than 10 seconds to cold start, as opposed to almost a minute in the previous version. Additionally, Hyper-V isn't a requirement anymore, so the steps detailed in this post work on Windows 10 Home.

Since WSL 2 in Windows and Docker Desktop is now GA, you can feel even more confident using your remote containers in WSL 2.

Getting started

Prerequisites:

Once installed, Docker will recognize that you have WSL installed and prompt you to enable WSL integration. Select Enable WSL integration from the pop-up window.

Docker Desktop WSL integration dialog

Optional: Install the new Windows Terminal for the best experience, including the ability to open new PowerShell and Ubuntu terminals in the same interface.

Open VS Code in WSL 2

Let's connect VS Code to our WSL 2 engine. Open an Ubuntu terminal, navigate to the source code folder of your choice, and type code .. This will launch an instance of VS Code that lets you use WSL as your full-time development environment. You can also connect to WSL from the Command Palette. I'm going to open a simple HelloNode application:

Launch code . from Ubuntu terminal

Once VS Code opens, it recognizes that we have WSL installed, and recommends we install the Remote - WSL extension. I'll select Install:

Remote - WSL extension recommended

After installing the extension, we can reload VS Code to connect to WSL 2:

Reload VS Code after installing extension

Once we've reloaded, we can confirm that we're connected to Ubuntu by checking the WSL indicator in the bottom-left corner of the window:

WSL: Ubuntu bottom left indicator

Installing the Remote - WSL extension added the Remote Explorer to VS Code. When we look inside the Explorer, we can see information about our Linux distros:

Remote Explorer with WSL Targets

Working with containers

We can leverage the Remote - Containers extension to view and attach to containers, in addition to a variety of other scenarios, such as:

These configurations allow you to easily recreate the same development environment across machines, install tools and extensions specific to a project into a DevContainer, and develop in a setup similar to the environment for deployment, leaving the local machine unchanged. We can also view and attach to containers using the Docker extension.

While you can access source code from both Windows and the WSL 2 filesystem when using the WSL 2 engine, we recommend using the WSL 2 file system because performance is much better. Since the performance is better when using the filesystem inside WSL 2, let's walk through how to use it.

We need to select the folder we want to open in a container. First, make sure you've installed the Remote - Containers extension. We can then call the Remote-Containers: Reopen Folder in Container command from a folder already opened using the Remote - WSL extension.

I have an existing HelloNode folder on my WSL 2 filesystem with my Node project in it. I'll select: Remote-Containers: Reopen in Container…:

Command Palette: Remote-Containers: Reopen in Container...

A list of container definitions will appear, since there is no DevContainer configuration in the repository yet. The list of container configuration definitions that appears is filtered based on my project type. I'll select Node.js 14:

Command Palette: Node.js 14

A new instance of VS Code opens. VS Code starts building the image, and then starts our container:

VS Code instance starting with Dev Container

Our application now has a .devcontainer folder in which the container configuration information is stored. To double-check we're connected to both WSL and within a container, let's open the integrated terminal and check for the uname and version of Node:

Check uname and node -v

As we can see, our uname came back as Linux, so we are still connected to the WSL 2 engine, and node -v returned v14.4.0, so we have successfully configured our Node 14 container.

Let's try running our app with F5:

Local host running Hello World app

Success!

Feedback & further reading

To help set up VS Code with WSL and containers, we have detailed articles on the VS Code Remote Development documentation. If you have any questions or feedback for our team, please feel free to open an issue on the VS Code Remote Development GitHub Repository or Tweet us @code.

Happy Coding!

Brigit Murtaugh, VS Code Program Manager @BrigitMurtaugh