Setting up Docker in Windows 11 using WSL2
September 19, 2024 | by Cícero Fabio
In this guide, I’ll walk you through my experience of setting up a development environment on Windows using containerized applications without Docker Desktop. While Docker Desktop is convenient, it’s no longer free, so I explored a cost-effective alternative using WSL2 (Windows Subsystem for Linux) and Ubuntu.
This process is streamlined to help you get Docker running on your machine quickly. If you’re familiar with Docker, Linux, PowerShell, and bash, you’re good to go!
Objective
We’ll set up a container runtime environment using WSL2, Ubuntu, and dockerd, enabling you to run containers from both Linux and Windows without Docker Desktop.
Prerequisites
- Enable WSL2 & Virtualization Features on Windows
Run the following commands in PowerShell to enable the necessary features:
Enable-WindowsOptionalFeature -Online -FeatureName 'Containers' -All
Enable-WindowsOptionalFeature -Online -FeatureName 'Microsoft-Hyper-V' -All
Enable-WindowsOptionalFeature -Online -FeatureName 'VirtualMachinePlatform' -All
Enable-WindowsOptionalFeature -Online -FeatureName 'Microsoft-Windows-Subsystem-Linux' -All
- Install Windows Terminal
Install the Windows Terminal from the Microsoft Store for a better console experience.
- Install Microsoft PowerShell
Install the latest version of PowerShell using the Windows package manager:
winget install --id 'Microsoft.Powershell' --scope machine
- Install Ubuntu (WSL)
Install the Ubuntu distribution via winget:
winget install Ubuntu
Once installed, set up your Linux user account.
Setting up Docker in WSL2 (Ubuntu)
- Update and Upgrade Packages
Open the Ubuntu terminal and update your packages:
sudo apt update && sudo apt upgrade
- Install Docker Prerequisites
sudo apt install --no-install-recommends apt-transport-https ca-certificates curl gnupg2
- Add Docker Repository
source /etc/os-release
curl -fsSL https://download.docker.com/linux/${ID}/gpg | sudo apt-key add -
echo "deb [arch=amd64] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/docker.list
- Install Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
- Add User to Docker Group
sudo usermod -aG docker $USER
- Configure Docker Daemon
Create a daemon.json
configuration file for Docker:
sudo mkdir /etc/docker/
sudo vi /etc/docker/daemon.json
Add the following contents:
{
"hosts": ["tcp://0.0.0.0:2375"],
"tls": false
}
- Launch Docker Daemon
sudo dockerd &
To stop the daemon, use:
sudo pkill dockerd
Verifying Docker Setup
- Check that Docker is working:
docker -H 127.0.0.1 run --rm hello-world
If successful, export the Docker host for future commands:
export DOCKER_HOST="tcp://127.0.0.1:2375"
Building Docker CLI for Windows
- Clone the Docker CLI repository:
git clone https://github.com/docker/cli.git
cd cli
- Build Docker CLI for Windows:
docker buildx bake
docker buildx bake --set binary.platform=windows/amd64
- Copy the
docker-windows-amd64.exe
to your Windows tools directory (e.g.,C:\tools
):
cp build/docker-windows-amd64.exe /mnt/c/tools
- Rename it to
docker.exe
:
cd c:\tools
ren docker-windows-amd64.exe docker.exe
Using Docker CLI on Windows
- Find the IP of your WSL host using PowerShell:
wsl -- ip -o -4 -json addr list eth0 | ConvertFrom-Json | %{ $_.addr_info.local } | ?{ $_ }
- Run a Docker command with your WSL IP:
docker -H <YOUR_WSL_IP> ps
- Optionally, create a Docker context for WSL:
docker context create wsl --docker "host=tcp://<YOUR_WSL_IP>:2375"
docker context use wsl
Automating IP Updates
WSL may change its IP address after each reboot, so create a PowerShell script to update the Docker context automatically:
$wslip = wsl -- ip -o -4 -json addr list eth0 | ConvertFrom-Json | ForEach-Object { $_.addr_info.local } | Where-Object { $_ }
$ctx = docker context ls --format json | ConvertFrom-Json | Where-Object { $_.Name -eq "wsl" }
if($null -eq $ctx) {
Write-Host "Creating Docker context 'wsl' to host=tcp://$($wslip):2375"
docker context create wsl --docker "host=tcp://$($wslip):2375" | Out-Null
} else {
docker context update wsl --docker "host=tcp://$($wslip):2375" | Out-Null
}
docker context use wsl | Out-Null
Now, your Docker environment is ready to go, without needing a Docker Desktop!
This clean and streamlined setup allows you to use Docker on Windows 11 with WSL2 and Ubuntu, all without the need for Docker Desktop!