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
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!