Get Docker For Windows

March 2, 2020 by Matt Hernandez, @fiveisprime

Last June, the Docker team announced that they will be investing in getting Docker running with the Windows Subsystem for Linux (WSL). All of this is made possible with the recent changes to the architecture of WSL to run within a lightweight virtual machine (VM), which we talked about in an earlier blog post about WSL 2. Since this announcement, the Docker team has released a Technical Preview of Docker that includes support for running with WSL 2.

This article explains how the Docker Desktop technical preview works as well as how to use the Docker extension with the technical preview.

I’m new to Docker. I am trying to run the label-studio tool in Docker Desktop 4.1.0 (69386) on Windows 10. I ran the following commands in a cmd with Docker Desktop started and logged in: docker pull heartexlabs/label. In this setup, Docker installs VirtualBox and use it as the Hypervisor. If you have Windows 10 64-bit Pro, Ent, or Edu and use VirtualBox, then follow method 2. Following the first method will make your VirtualBox VMs inoperable. Before you begin, enable Intel VT-x hardware virtualization in BIOS or UEFI firmware.

How it works

This new Docker architecture works a lot like Visual Studio Code's WSL remote development support in that the Docker CLI running on the host machine executes commands within the Docker Integration Package, which runs on the remote WSL VM.

Image credit: Docker Engineering

DockerD runs directly within WSL so there's no need for the Hyper-V VM and all Linux containers run within the Linux userspace on Windows for improved performance and compatibility.

Getting set up

First some prerequisites:

  • Install Windows 10 Insider Preview build 18975 (Slow) or later for WSL 2.
  • Install Ubuntu from the Microsoft store.
  • Enable WSL 2 by following this guide.
  • Install the Remote - WSL extension for VS Code.
  • Install the Docker WSL 2 Technical Preview.

Once installed, Docker will recognize that you have WSL installed and prompt to enable WSL integration. You want to Enable WSL integration for this tutorial.

This option will allow you to access Docker Desktop via the Docker CLI directly from within your Linux distro.

If you have multiple Linux distros, make sure you only have WSL integration turned on for the correct one in your Docker settings:

With that configured, all commands will execute in the Linux context - this includes Docker commands run from PowerShell so running something like docker run mongo… will start a Linux container within the WSL VM.

Running the docker ps command over in WSL, you'll see the container as expected. Notice that the container ID matches.

Using VS Code

With this set up and running, you can install the VS Code Docker extension and access your containers. If you're already running WSL 2 and the Remote - WSL extension, this will help you get Docker integrated into your WSL workflow rather than switching contexts when you need containers. And because the Docker CLI's context is set to use DockerD in WSL, the extension will work with your containers regardless of whether you opened VS Code using the Remote - WSL extension.

Notice how in the screenshot below, I'm connected and working in WSL and still building/running containers without changing from my preferred environment (zsh in Ubuntu).

Theme: Noctis Sereno

I've personally noticed a vast improvement in container execution times using this configuration and each part of my typical development workflow remains the same. I'm also using the Remote - Containers extension within WSL for testing specific environments without setting things up directly on my machine.

We want your feedback

Keep in mind that you're using prerelease software and, while the Windows Insiders Slow ring is very stable, you may run into some issues. If you do find something that isn't working as expected, please open an issue via the Feedback tool in Windows. Any direct Docker issues or feedback can be logged in the Docker for Windows repo.

Happy Coding!

Matt Hernandez, VS Code Program Manager @fiveisprime

Docker for Windows makes it super easy to get an IIS server up and running (if you’ve not tried Docker for Windows yet, check out my getting started guide). With the following PowerShell commands, we can get an IIS container running, discover it’s IP address, and launch it in a browser:

And we can see that our IIS instance is indeed up and running:

But how can we get our own HTML files into our container? Well, Docker gives us a variety of techniques. Let’s look at four.

Technique 1: Edit in the Container

The first technique is the least practical, but demonstrates a very powerful feature of Docker containers. We are not limited to running just one process in them. So while our datatest1 container is running IIS, we can also run PowerShell in it like this:

Windows

This gives us an interactive command prompt inside our container.

So we can create our own index.html file in there:

If we refresh our browser, we can see our edit has worked:

Now clearly this would not be a practical way to construct a website, but it does demonstrate that you can connect into a running container and make any changes you need. This is a technique you might use while experimenting with a container, with a view to scripting your manual changes in a dockerfile (see technique 4 below) later.

Get Docker For Windows Stable

Technique 2: Copy into a Container

The second technique is to use the docker cp command. This allows you to copy files locally into a container. So I made a local index.html file which I attempted to copy into my datatest1 container

But this fails with an error saying the file is in use. In fact, I couldn’t manage to copy any file anywhere while the container was running. I don’t know whether this is a limitation with Windows containers, or if there is a way to get this working, but it does at least work while the container is stopped. Unfortunately this will mean the container will also get a new IP address.

If instead of copying a single file, we want to copy the contents of a whole local folder called site into wwwroot, then I couldn’t find the right syntax to do this directly with docker cp, so I ended up changing local directory before performing the copy:

So while docker cp is a useful command to know, it still isn’t the smoothest experience.

Technique 3: Mount a Volume

This next technique is a really nice feature of Docker. Rather than transferring our data into the container, we can make a folder on our local machine visible inside the container by mounting a volume.

We do this with the -v switch on the docker run command, specifying the local folder we want to mount, and the location in which it should appear on the container.

There were a couple of quirks I ran into. First of all, the local path needs to be absolute, not relative, so I’m using Get-Location to get the current directory. And secondly, you can’t mount a volume on top of an existing folder (at least in Docker for Windows). So we sadly can’t overwrite wwwroot using this technique. But we could mount into a subfolder under wwwroot like this:

Get Docker Toolbox For Windows

And we can see the results in a browser with a similar technique to before:

Get Docker For Windows 10

Now the great thing is that we can simply modify our local HTML and refresh the browser and our changes are immediately visible.

So volumes are a really powerful technique, and really come into their own when your container needs to store data that needs to live beyond the lifetime of the container.

Get Docker For Windows

But there’s one final technique we need to consider for getting our HTML into our container, and that’s using a dockerfile.

Install Docker For Windows 7

Technique 4: Use a Dockerfile

Get Docker For Windows 8

While volumes are great for data, if you’re planning on deploying your website, you probably do want to bake the HTML into the container image directly. And that can be done by creating your own dockerfile. This is about the simplest sort of dockerfile you can create:

All this dockerfile is saying is that our base image is the Microsoft IIS nanoserver image from DockerHub, and then we want to copy the contents of our local site directory into C:/inetpub/wwwroot.

Install Docker For Windows 10 Home

With our dockerfile in place, we need to build an image with the docker build command, giving it a name (I chose datatest4:v1), and then we can create a container from that image with docker run, just as we did before.

Get Docker For Windows Server 2016 Edge

The great thing about this approach is that now we have an image of our website that we can deploy anywhere.