In this post I give a short summary of using Docker on Windows and a more detailed view into the newest Docker Desktop version in combination with WSL 2. If you would like to learn the basics of WSL 2, please take a look at my earlier post.
There is not ‘the’ single point of truth when working with Docker on a Windows machine. You have several options to choose from, each with their benefits and downsides. However, as Docker is a ‘Linux solution’ you will end up with some kind of virtualized Linux environment running on your Windows system. You can decide to run and set up your own full-grown virtual machine (VM) yourself. Or you go for the current ‘Windows solution’ and use Docker Desktop. If you don’t have the latest Windows 10 version, you may stick to Docker Machine, however, it is superseded for quite some time now.
As of May 2020 (release 188.8.131.52) Docker Desktop is now also available for Windows 10 Home users, due to the new Windows Subsystem for Linux (WSL) 2 backend.
Docker on Windows: It’s your choice
The classic solution would be to set up your own virtual Linux machine, e.g. with VirtualBox and running Docker from there. Especially when you run a fully dockerized environment (and this in production), which does not care about any Windows application or service, this still seems to be the most reasonable solution. You can choose between virtualization tools like VirtualBox, VMware or Microsoft’s Hyper-V.
In theory you will need to set everything up like file-sharing, port-forwarding and networking in general. This is crucial especially when you want to have a smooth interoperability between your Windows host and your Linux machine. However, all virtualization tools will assist you there.
A small detour: Use Vagrant to set up your Docker VM
An even easier solution is, to make use of Vagrant to build and configure a custom VM. As long as you or someone in your project team knows how to write a Vagrant file, it provides quite a simple workflow to set up your docker environment. Once written, it allows to simply share a complete development environment without the need to share ‘full grown’ VDIs. However, you will still have a full VM running on your host. This always leads to some overhead when you only want to run Docker on Windows. In addition, you now have two separate systems. There the interplay is not always as smooth as you want it to be, especially doing it for the first time.
I started playing around with Docker in the browser, which allows access to Docker within seconds. When I really began using it, I simply chose the ‘Windows solution’ and installed Docker Desktop. It required Hyper-V to run a VM in the background and was hence not available for Windows Home users (2019). It worked out of the box and for the first small projects I experienced quite a flawless usability. However, as a project required me to install VirtualBox I had to disable the Windows Hyper-V feature. Switching between both Windows states requires a full system reboot, so this was no option for me.
That’s why I moved to Docker Machine for a while. Instead of requiring Hyper-V, it allows to connect to a Docker engine on a remote system or within any VM. This ‘legacy’ solution has its flaws with respect to usability compared to Docker Desktop. For example, you cannot connect to your containers via localhost. However, for me it provided some valuable insights into working with a remote Docker daemon. It was also the only option for Windows Home users and still is if you do not run Windows 10! So, both applications rely on an actual Linux VM running. But they are running in the background and you don’t have to touch them yourself.
When I heard that Docker Desktop switched to WSL 2 instead of Hyper-V as backend, I gave it another try.
Docker Desktop on Windows using WSL 2
The advantages of WSL 2 over the previously used VM promises to improve the integration and a reduced footprint. As this is the way that Microsoft and Docker Inc. work on in cooperation, this is the solution I wanted to investigate further. If you don’t know about WSL2 in general, read my last blog post.
Just to mention it, Docker was trying to run its daemon within WSL1 but had big difficulties doing so as for example systemd is not available in WSL 1. Some hacky workarounds exist and it is possible to interact with the Docker daemon via Docker Desktop from within WSL.
Get Docker Desktop with WSL 2 backend
- As a Windows Home user, you need at least Windows 10 version 2004 or higher.
- Pro, Enterprise and Education need at least Windows 10, updated to version 1903 or higher.
- In addition, ‘Virtual Machine Platform’ and ‘Windows Subsystem for Linux’ features must be enabled.
When you meet the requirements, you can follow these installation instructions. Next to the Windows features, ‘Virtual Machine Platform’ and ‘Windows Subsystem for Linux’, also check that WSL2 is enabled in your Docker Desktop settings (default by now).
The announcement to switch from the Hyper-V backend to WSL 2 triggered quite some attention. Especially from users that wanted to use Docker Desktop in parallel to third-party virtualization software bypassing Hyper-V.
However, WSL2 itself does rely on Hyper-V components. The problem with using additional virtualization platforms in parallel to Docker Desktop persists for now!
Another small detour: Hyper-V and third-party virtualization Using a third-party virtualization in parallel with Hyper-V is not possible. Therefore, current versions of VirtualBox (since 6.0) and VMware (since 15.5.5) offer to use Hyper-V as a fallback solution to their own virtualization technology. This allows them to still function when Hyper-V is enabled on the host system. However, in both cases this leads to a significant performance loss up to the point that you can’t boot your VM anymore. In my case for example I cannot boot a Windows 10 (x64) VM using VirtualBox. While when playing around with Docker on a small Linux machine, I set up using Vagrant, I didn’t directly notice a performance drop. So, there is still a way to go and from my experience and others I would make the statement:
Hyper-V needs to be disabled if you work with third-party virtualization
Architectural design of Docker Desktop on WSL 2
The architectural approach to implement Docker Desktop on WSL 2 is quite close to the previous Hyper-V solution.
Instead of running inside a ‘standard’ Hyper-V VM it runs in the light-weight utility VM provided by WSL 2. To adapt for the WSL 2 design, it had to handle that different user distros will be running in the same VM, sharing the same network namespace. Running two docker daemons in two different user distros would not work. Therefore, Docker Desktop comes with two customized distributions.
NAME STATE VERSION docker-desktop Running 2 docker-desktop-data Running 2
docker-desktop is basically running the previous LinuxKit distro, now as a container inside a WSL 2 ‘bootstrapping’ distribution, which allows namespace isolation. The container services stayed the same, however the Linux Kernel is removed with the Kernel provided from WSL 2.
docker-desktop-data is used for data storage replacing the VHD. Its directories are bind-mounted inside the LinuxKit container. An API proxy allows to share data and the Docker daemon with other user distros. As this distro contains all the data needed by Docker, it can can get huge quite fast. The data is located at
C:\Users\<username>\AppData\Local\Docker\wsl\data\ext4.vhdx. As described in my previous post, you should clean up some disk space from time to time using
optimize-vhd (Hyper-V) or diskpart. For example when you had some big docker images in use which you don’t need any more. This seems to be way easier compared to a VirtualBox VM.
What is new with Docker on WSL 2
In terms of usability there is no obvious change when using Docker from the command line. However, you can now use the docker command either from Powershell on Windows or from within any Linux distribution you want. Therefore, you only need to enable it within Docker Desktop settings.
Sharing the same Docker daemon and also the same Linux kernel and file system cache allows faster bind-mount performance as well. The directory
/mnt/wsl/ is shared between all distros and contains also the shared mount points. This is achieved with the API proxy, intercepting container commands and rewriting paths to the shared ones.
The same applies as well to the Kubernetes integration into Docker Desktop.
Benefits from WSL 2
- Docker Desktop is now available to Windows 10 Home users as well. It does not require the Hyper-V feature. It still uses Hyper-V components provided by ‘Virtual Machine Platform’ and ‘Windows Subsystem for Linux’ features.
- Docker Desktop aims to provide a seamless operation of Docker on Windows. This boils down to achieve the highest possible integration of the underlying VM. The (Microsoft) WSL2 light-weight utility VM provides tighter integration on the Windows host as Docker’s previous Hyper-V solution.
- The startup times for the Docker daemon on the WSL2 backend are way faster (~ 5-10x).
- The Hyper-V solution offered tight integration of Docker into your Windows environment. WSL 2 provides integration of a full Linux development environment and Docker and your Windows host.
- It is the way that Microsoft and Docker Inc. highly cooperate on. WSL2 is still evolving and promises more to come…
Drawbacks from WSL 2
The drawbacks are mainly connected to the WSL 2 integration to the Windows host. The Docker daemon is running within WSL 2 with almost native Linux performance. To benefit from that the code base should also be moved to the Linux file system. Issues with memory consumption were improved with the latest WSL 2 releases.
With WSL 2, Windows continues to move towards integrating a full Linux environment for Windows developers. This allows to integrate Docker within a mixed development environment. But does this finally allow a decision for the ‘Windows solution’ over the classical Linux VM? It certainly leverages the Docker user to additionally configure a VM and it works out of the box. The cooperation between Docker and Microsoft will improve and new features will be added. With the classic solution on the other hand, you will have more control over the configuration.
Thanks for reading and I hope I could motivate you to try out Docker with WSL 2.