Part IIb: Setup WSL and Docker
This is Part IIb of a 3 1/2-part blog post on how I configured my working environment. Here I’ll explain how to configure WSL together with Docker. Note that I do not use Docker on Windows very often these days. I mainly connect to VMs via WSL and use Docker remotely. However, sometimes, Docker on Windows may become handy - have a look at the instructions below on how to configure WSL together with Docker on Windows.
- Part I: Setup Dev Environment in Windows
- Part IIa: Windows Subsystem for Linux (WSL)
- Part IIb: WSL & Docker setup
- Part III: Installation of additional packages and tools in WSL
Install Docker
You want to be able to run docker-compose and docker client from WSL1, but the backend needs to be run through native Windows 10 Docker Server. Therefore, install Docker Desktop for Windows 10 first.
Option 1: Install with Chocolatey Package Manager with choco install docker-desktop
Option 2: Download from here and install manually
Setup Docker
In Docker Desktop (Windows), under General, make sure you uncheck Expose daemon on tcp://localhost/2375 without TLS
.
Also, disable Use the WSL 2 based engine
.
Under Shared Drives,
select the drive where you keep your project folders (e.g. docker-compose.yml
etc.).
This will allow docker from WSL1 access files on this drive,
which is necessary if you want to execute docker-compose in a folder on d:
.
I’ve also changed some of the Resource/Advanced settings to fit my needs:
As you can see, I’ve also changed the location where Docker stores my virtual containers to D:
From now on, we’re working in the WSL bash (open with right-click and Open WSL bash here
).
- Update the apt package list.
sudo apt-get update
- Install Docker’s package dependencies.
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
- Download and add Docker’s official public PGP key.
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- Use the following command to set up the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- Install Docker Engine
sudo chmod a+r /etc/apt/keyrings/docker.gpg
sudo apt-get update
- Install Docker Engine, containerd, and Docker Compose.
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- Allow your user to access the Docker CLI without needing root access.
sudo usermod -aG docker $USER
Docker Compose
There is no need to install docker-compose anymore.
docker compose
is now available by default (note the missing -
in the command)
Setup secure WSL1-Docker connection
A secure connection between WSL1 and Docker Desktop is available
through socat
1 and
npiperelay.
Connect WSL1<->Docker the insecure way?
The steps to set up npiperelay
:
- Install Socat and tmux
- tmux for starting the relay in a background session
- socat for the docker relay stream
sudo apt update && sudo apt install socat tmux
- Get the the
npiperelay.exe
and setup connection
You need to use your Windows username (/c/Users/<username>
).
Export your Windows user name as a variable:
export wuser=<username>
Get npiperelay.exe
from Github releases,
build, and store in Windows user directory:
cd /c/Users/$wuser/
mkdir -p go/bin/
wget -O \
go/bin/npiperelay_windows_amd64.zip \
https://github.com/jstarks/npiperelay/releases/download/v0.1.0/npiperelay_windows_amd64.zip
unzip -d go/bin/ go/bin/npiperelay_windows_amd64.zip
rm go/bin/npiperelay_windows_amd64.zip
Symlink npiperelay.exe
from Windows to WSL1:
sudo ln -s \
/c/Users/$wuser/go/bin/npiperelay.exe \
/usr/local/bin/npiperelay.exe
Get docker-relay
script and run as background task:
cd ~
git clone https://github.com/jstarks/npiperelay.git
sudo ln -s ~/npiperelay/scripts/docker-relay /usr/local/bin/
chmod +x /usr/local/bin/docker-relay
We modify docker-relay so it starts the Socket inside the user directory.
mkdir ~/sockets
nano /usr/local/bin/docker-relay
Add the following. Make sure to replace {replace-with-your-username}
with your WSL1 username.
#!/bin/sh
SOCKET=/home/{replace-with-your-username}/sockets/docker.sock
if [ -e $SOCKET ]; then rm $SOCKET; fi
exec socat UNIX-LISTEN:$SOCKET,fork,group=docker,umask=007 EXEC:"npiperelay.exe -ep -s //./pipe/docker_engine",nofork
Store with CTRL+O.
I also had to manually remove the docker.sock
and symlink with the new one:
cd /var/run
sudo rm docker.sock
sudo ln -s /home/alex/sockets/docker.sock /var/run/docker.sock
Test it with:
sudo docker-relay &
docker info
> Client:
> Context: default
> Debug Mode: false
> Plugins:
> app: Docker App (Docker Inc., v0.9.1-beta3)
> buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
> scan: Docker Scan (Docker Inc., v0.8.0)
You may need to add permissions to the docker-sock
:
sudo chown $USER:$USER /home/$USER/sockets/docker.sock
To autostart the relay, we need to add these lines to ~/.bashrc
:
# set WSL env; configure secure Docker connection through
# socat and npiperelay
if cat /proc/version | grep Microsoft > /dev/null; then
export WSL=true
fi
if [ "$WSL" ]; then
export DOCKER_HOST="unix://$HOME/sockets/docker.sock"
if ! pgrep socat > /dev/null; then
tmux new -s docker-relay-session -d docker-relay
fi
fi
(nano ~/.bashrc
)
Finally, some commands may use sudo
to start docker. In this case,
DOCKER_HOST
will not be available. Modify sudoers to keep this entry:
sudo nano /etc/sudoers
and add the following line:
Defaults env_keep += DOCKER_HOST
Test docker in WSL
Restart Docker for windows!
docker run hello-world
Some additional information for working with WSL & Docker follow below.
Fix Docker Connectivity Bug
There seems to be a bug, where Docker on Windows 10 may see errors similar to this after restarting the computer:
Cannot restart container my_container: driver failed programming external connectivity on endpoint my_container
...
The steps described below may solve this issue.
How to disable fast startup on Windows 10
Disable it in just a few steps:
- Right-click the Start button.
- Click Search.
- Type
Control Panel
and hit Enter on your keyboard. - Click
Power Options
. - Click
Choose what the power buttons do
. - Click
Change settings that are currently unavailable
. - Click
Turn on fast startup (recommended)
so that the check-mark disappears. - Click
Save changes
.
Annoying WSL bug: Missing Access rights
Now this may occur on very few occasions, only for WSL1 - for me it happened mainly when building
python packages (e.g. setuptools
, distutils
, pypi
). Since the latest Windows Update,
some access rights changed and those affect how
packages in WSL can access folders.
Wherever you keep your code, right click main folder, select Security and allow “Full Access” to authenticated users.
Update from WSL 1 to WSL 2
Fix Docker Connectivity after WSL2 upgrade
If you used WSL1 before, there may be an entry in ~/.bashrc
file that must be removed.
Removed
export DOCKER_HOST=tcp://localhost:2375
from~/.bashrc
;Disabled
Expose daemon on tcp://localhost:2375 without TLS
in Docker Desktop;Enabled
Use the WSL 2 based engine
in Docker Desktop
See WSL/issues/4321