This file outlines the steps taken to install and run Docker on Windows (WSL2) without Docker Desktop. To mimic the existing experience, those steps will guide you through creating a separate Linux distribution to host the Docker engine.
Distribution | Location |
---|---|
Ubuntu-20.04 (Focal Fossa) | https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64-wsl.rootfs.tar.gz |
Ubuntu-22-04 (Jammy Jellyfish) | microsoft/WSL#8402 |
.\CreateLinuxDistro.ps1 `
-INPUT_FILENAME <path-to-linux-distro-tarball> `
-OUTPUT_DIRNAME "$env:LOCALAPPDATA\Packages\<distro>" `
-OUTPUT_DISTRONAME <distro> `
-CREATE_USER 1 `
-CREATE_USER_USERNAME <username> `
-ADD_USER_TO_GROUP 1 `
-ADD_USER_TO_GROUP_NAME sudo `
-SET_USER_AS_DEFAULT <username>
For instance, I named my <distro> ubuntu-docker
and created a new <username> docker
.
You can use the following command to retrieve the IP address from the WSL2 instance:
`ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'`
- Configuration
- Add
<username>
to the list of/etc/sudoers
and prevent password prompt
<username> ALL=(ALL:ALL) NOPASSWD:ALL
- Install docker-ce-cli on another instance.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce-cli
- Update the docker host
As Docker is running in a separate WSL2 instance, the DOCKER_HOST
environment variable must be updated.
Add this to the ~/.bashrc
file:
# Docker is hosted on another WSL2 instance
#
ip=`wsl.exe -d <distro> sh -c "hostname -I | cut -f1 -d ' '"`
export DOCKER_HOST="tcp://$ip:2375"
- Install docker-compose utility
docker-compose
is a separate binary which can be downloaded from the project’s GitHub releases page.
Locate the latest version number and install using the following command:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
The docker
CLI for Windows can be downloaded from:
https://github.com/StefanScherer/docker-cli-builder/releases
The docker-compose
CLI for Windows can be downloaded from:
https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-windows-x86_64.exe
Use the following scripts to start and stop Docker.
$Env:DOCKER_HOST="tcp://localhost:2375"
Function Start-Docker {
$ip = (wsl -d <distro> sh -c "hostname -I").Split(" ")[0]
Write-Host "netsh interface portproxy add v4tov4 listenport=2375 connectport=2375 connectaddress=$ip"
$arguments = "interface portproxy add v4tov4 listenport=2375 connectport=2375 connectaddress=$ip"
Start-Process netsh -ArgumentList $arguments -Verb RunAs
Start-Job { param([string]$ip) wsl -d <distro> sh -c "sudo dockerd -H tcp://$ip" } -ArgumentList $ip | Out-Null
}
Set-Alias -Name dockerd -Value Start-Docker
This retrieves the current IP address from the WSL2 Docker instance and sets up port forwarding from the local host address to the WSL Docker instance. This requires elevated privileges.
Once that is setup, a pwsh background job is started to run the dockerd
daemon in the WSL2 Docker instance.
Please, wait for a few seconds, and test that Docker is running with the following command:
docker -H tcp://localhost:2375 ps -a
You can make the -H tcp://localhost:2375
a default value by creating the DOCKER_HOST
environment variable.
Function Stop-Docker { wsl --terminate <distro> }
Set-Alias -Name rmdocker -Value Stop-Docker
This will terminate the WSL2 Docker distribution.
You can install Minikube in another WSL2 instance. We will take advantage of the previous Docker installation.
- Follow the steps outlined earlier to create a new distribution
For instance, I named my <distro> ubuntu-minikube
and created a new <username> kube
.
Log in to the WSL2 ubuntu-minikube
instance and:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb
- Configuration
- Add
<username>
to the list of/etc/sudoers
and prevent password prompt
<username> ALL=(ALL:ALL) NOPASSWD:ALL
As Docker is available from another WSL2 distribution, add the following commands in ~/.bashrc
:
# Docker is hosted on another WSL2 instance
#
ip=`wsl.exe -d ubuntu-docker sh -c "hostname -I | cut -f1 -d ' '"`
export DOCKER_HOST="tcp://$ip:2375"
The kubectl
CLI tool can be downloaded from:
https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/
Use the following command to start Kubernetes
Function Start-Kubernetes {
wsl -d ubuntu-minikube sh -c "/home/kube/minikube.sh start --embed-certs"
wsl -d ubuntu-minikube sh -c "cp ~/.kube/config /mnt/c/Users/$($env:USERNAME)/.kube"
}
Set-Alias -Name k8s -Value Start-Kubernetes
This command start Minikube from its WSL2 distro with the --embed-certs
command-line option.
This makes the certificates available in the ~/.kube/config
file.
Those certificates can then be copied to the Windows host username folder for kubectl
to find them.
To enable Kubernetes from other WSL2 distributions, you can run the following command:
[[ ! -L ~/.kube/config ]] && ln -s "/mnt/c/Users/`cmd.exe /c "echo|set /p=%USERNAME%" 2>/dev/null`/.kube/config" ~/.kube/config
You can use the following command to manage Minikube from Windows.
Function minikube { wsl -d ubuntu-minikube sh -c "/home/kube/minikube.sh $args" }
Function Stop-Kubernetes { wsl --terminate <distro> }
Set-Alias -Name rmkube -Value Stop-Kubernetes
Set-Alias -Name rmk8s -Value Stop-Kubernetes
This will terminate the WSL2 Docker distribution.