Install Docker on WSL 2 with VPN Support to replace Docker for Windows

Robert Diers
NEW IT Engineering
Published in
6 min readSep 20, 2021

--

Motivation

  • Docker for Windows will have a paid plan in the future
  • Docker on WSL 2 has better performance (my opinion)
  • I like to work on Linux

What do we want to achieve?

We want to run Docker native on Debian WSL 2 and use PowerShell to send “docker” commands to the WSL. Docker for Windows is not required anymore.

Main pain point is VPN integration, this is fixed using a really great open source solution. (successfully tested with corporate VPN based on Pulse Secure — I can connect to external and internal sites)

EDIT: Using VPN a docker container is not able to communicate with external servers in Internet or your VPN network, to get this working you will need to use host network including all consequences.

--network host

Step-by-Step

#1 Disconnect from VPN (if connected)

#2 Deinstall Docker for Windows, Feature “Subsystem for Windows” should stay active:

#3 Define Version 2 as default for WSL (cmd)

wsl --set-default-version 2

#4 install VPN solution from here — thanks for this GREAT WORK!

Download latest release from here: https://github.com/sakai135/wsl-vpnkit/releases/latest

(deactivate Windows feature Hyper-V if enabled)

Open CMD in Downloads folder and import the distribution (cmd):

wsl --import wsl-vpnkit wsl-vpnkit wsl-vpnkit.tar.gz

Should look like this now:

#5 Grap Debian from MS Store and open it using Start panel from Windows

(should take a few seconds and will ask for username and password).

Should look like this when done:

#5 update Debian and upgrade packages (shell)

sudo apt update
sudo apt upgrade

#6 Connect to your VPN, Debian will loose network connectivity

#7 Start VPN Fix to restore it (cmd)

wsl -d wsl-vpnkit
wsl.exe -d wsl-vpnkit service wsl-vpnkit start

Much better:

At this point you might want to install curl and try to access a web page within your VPN network.

#8 Install Docker

I will not copy every command from the linked page, but you should get something like this:

#9 Fix Docker in Debian WSL 2 (shell)

sudo touch /etc/fstab
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo service docker start

#10 Run Docker without sudo (shell)

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world

YEAH!

#11 PowerShell Script to communicate with WSL 2 Docker (optional)

Create File C:\Users\<userid>\Documents\WindowsPowerShell\profile.ps1

Please use your Linux user here:

function docker {wsl -d debian -u <linux-user> -e docker $args}

Depending on your corporate rules you might not be allowed to use this script, PowerShell will inform you about this with a red message directly after PowerShell startup.

This can be fixed running a Powershell as Administrator and executing the following line:

Set-ExecutionPolicy remoteSigned

At this point you might want to inform yourself about execution policies…

# 12 DONE — should look like this

I would recommend to disconnect from VPN, try accessing an external web page, connect again and try a internal one. (VPN fix should handle DNS and everything else)

Things you need to know!

Docker is running in Debian, you should think about this when using volumes. Up to now I was not able to try it, but I think you need to use the Linux paths:

/mnt/c/Users/<windows-userid>/…

To be honest, I cannot recommend to use this shared folder as performance will decrease. You can simply store your files within the WSL 2 instance and access them with tools like Visual Studio Code Server:

Docker GUI

You might want to have a replacement for Docker GUI — we can use Portainer for this:

docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

Have you seen it? Everything executed in Powershell ;-)

Now you can open your favorite browser: http://localhost:9000/

Add local Docker engine as Endpoint:

Now you should be able to see your running portainer instance and all containers you might want to use in future…

Feel free to clap for this article if you found it useful and check out my other articles dealing with Visual Studio Server (as mentioned I would not recommend to store code on share Win-Linux drive).

Good Luck!

Restart

After Windows restart it is required to activate VPN fix using the following command:

wsl.exe -d wsl-vpnkit service wsl-vpnkit start

Sometimes the Docker fix seems to get “lost”, but can be restored with:

sudo touch /etc/fstab
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo service docker start

Feel free to add automation ideas in the comments ;-) For restart I simply used a cmd executed each startup, I think I will add the other commands as well…

EDIT 2021–11–30:

A colleague gave me another hint…

Windows: Create a file “docker.cmd” with content:

@wsl -d debian -u <userid> -e docker %* 

and add to you PATH variable, Execution-Policies Powershell not required anymore.

Git-Bash: Create a file “docker” with content:

#!/bin/bashwsl -d debian -u <userid> -e docker "$@"

and add to $PATH.

--

--