Docker in Ubuntu on WSL2

Today Docker is a must-have tool for developers, some times for simple testing or development, and Docker Desktop is a good choice for Windows user, but it’s not free for commercial use when you work in a company. So I prefer to use Docker in WSL2, it’s free and easy to use.

Prerequisite

  • Windows 10 or 11
  • WSL2

Install WSL2

  • Install WSL2 (refer to WSL2)
wsl --install
  • Be sure to set WSL2 as default version
wsl --set-default-version 2
  • Install Ubuntu 20.04 or 22.04
wsl --install -d Ubuntu20.04

Install Docker

All the following commands are executed in WSL2 Ubuntu Commands below are from Docker Official Site

  • Remove old versions
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
  • Set up the repository
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
  • Install Docker Engine
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  • Try to run hello-world
sudo docker run hello-world

Init Docker Service on Boot

Create /etc/wsl.conf and add the following content otherwise, you need to start docker service manually after each boot

[boot]
command = "service docker start"

Issue I met with Ubuntu 22.04

After init docker service, console will show you

sudo service docker start
* Starting docker:docker    [ OK ] 

But actually docker service is not running, you can check it by

sudo service docker status
* Docker is not running

That’s because Ubuntu 22.04 LTS uses iptables-nft by default. You need to switch to iptables-legacy to make docker work.

sudo update-alternatives --config iptables
# There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).

#   Selection    Path                       Priority   Status
# ------------------------------------------------------------
# * 0            /usr/sbin/iptables-nft      20        auto mode
#   1            /usr/sbin/iptables-legacy   10        manual mode
#   2            /usr/sbin/iptables-nft      20        manual mode

Choose 1 to switch to iptables-legacy, then restart docker service


Port Forwarding from WSL2 to Windows

Now you can run docker in WSL2, but you can’t access the service from Windows, because WSL2 is running in a virtual machine, and it has its own IP address. use powershell as administrator to create port forwarding

netsh interface portproxy set v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$(wsl hostname -I)

If still not working, try to disable firewall

netsh advfirewall firewall add rule name="WSL2 Forward Port 8080" dir=in action=allow protocol=TCP localport=8080

Testing

Run new nginx container in WSL2

docker run -d -p 8080:80 --name nginx nginx

Receive response from Windows nginx

Use Docker direct from Windows cmd or powershell

Now you can use docker in WSL2, but you still need to open WSL2 and run docker command in it, if you want to use docker command in Windows cmd or powershell, you can create a simple script to forward the command to WSL2

PowerShell

  • Create file Microsoft.PowerShell_profile.ps1 in $env:USERPROFILE\Documents\WindowsPowerShell
cd $env:USERPROFILE\Documents
md WindowsPowerShell
cd WindowsPowerShell
New-Item Microsoft.PowerShell_profile.ps1 -ItemType "file"
# Microsoft.PowerShell_profile.ps1
function docker {
    wsl docker $args
}
  • Restart PowerShell Session

CMD

  • Create file docker.cmd in any folder, and add folder to system path
@echo off
wsl docker %*
  • Restart CMD Session

WSL2 Setting

  • The command from execute from Windows will not run as root in WSL2, so you need to add your user to docker group
sudo usermod -aG docker $USER
  • Restart WSL2, and you are all set!

ref:

comments powered by Disqus