This is, to the best of my knowledge, the optimal way to install Docker under Windows if you don’t have a Docker Desktop license.
The Problem
You need Docker on your Windows work machine, but you:
- don’t have access to a Docker Desktop license;
- don’t want to buy one;
- work for someone who doesn’t want to buy one for you either.
Disclaimer
I AM NOT A LAWYER, AND THIS IS NOT LEGAL ADVICE.
Docker Desktop is licensed under the Docker Desktop license agreement, which makes it “free for small businesses (fewer than 250 employees AND less than $10 million in annual revenue), personal use, education, and non-commercial open source projects.”
Docker Engine and the Docker CLI are licensed under the Apache License 2.0.
To me, that means that if you work for a business with more than 250 employees or more than $10 million in annual revenue you are not allowed to use Docker Desktop, but you can still use the Docker Engine and the Docker CLI.
Also, if you follow this guide and bad things happen (you get sued, your computer explodes, you lose the love and trust of your friends and family), it’s not my fault.
The Solution
We will
- install WSL2;
- install
docker
inside WSL2; - configure it as a
systemd
service; - use
docker
inside WSL to build the cli executable for Windows.
This will allow us to use the docker
command from PowerShell, VS Code or any other tool that relies on the existence of docker
on the Windows PATH
.
Prerequisites
- Go grab a cup of coffee, tea, or your favorite beverage.
- Install PowerShell 71.
- Install Windows Terminal from the Microsoft Store or GitHub (optional, but highly recommended if you want to keep your sanity instead of having to manage multiple console windows at the same time).
- Set PowerShell 7 as the default shell in Windows Terminal (again, optional but highly recommended).
- Install WSL2.
- Install Ubuntu 22.04 from the Microsoft Store, or from this direct link.
- Enable
systemd
in WSL2:sudo -e /etc/wsl.conf
- Add
[boot] systemd=true
- Save and exit.
- Restart WSL2 from PowerShell:
wsl --shutdown
.
Install Docker
Install Docker inside WSL2.
Add your user to the
docker
group:sudo usermod -aG docker $USER
.Override the
docker.service
file:sudo systemctl edit docker
adding the following text[Service] ExecStart= ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
between
### Anything between here and the comment below will become the new contents of the file
and
### Lines below this comment will be discarded
In this way, Docker will listen on a TCP socket on port
2375
(feel free to change it if you want) and we will be able to connect to the Docker Engine from Windows.Reload the
systemd
daemon:sudo systemctl daemon-reload
.Restart the Docker service:
sudo systemctl restart docker.service
.Enable the Docker service to start automatically:
sudo systemctl enable docker.service
.Optionally, you can install
keychain
to make sure you WSL will not be killed when you close the last shell window2:sudo apt update && sudo apt install keychain -y
sudo -e /etc/profile.d/keep_wsl_running.sh
- Paste this
#!/usr/bin/env sh eval $(keychain -q)
- Exit from WSL.
- Start a new WSL shell.
- From now on, when you really want Windows to kill the WSL session, use the command
keychain -k all
before closing all the WSL windows.
Build the docker
CLI
This is the worst, but I haven’t found a way to avoid it.
- Install
git
:sudo apt install git
. - Clone the docker cli repository:
git clone --depth 1 --branch v24.0.4 https://github.com/docker/cli && cd cli
. docker context create build_windows
.docker buildx create build_windows
.docker buildx bake --set binary.platform=windows/amd64
.- While you wait for the build to end, think about your life and the choices that brought you here. The build takes a couple of minutes to complete on my machine.
- Your new
docker-windows-amd64.exe
will be in thebuild
folder of the repository. - Create a directory under C: (or wherever you want) called
docker-cli
:mkdir /mnt/c/docker-cli
. - Move
docker-windows-amd64.exe
to that folder:mv build/docker-windows-amd64.exe /mnt/c/docker-cli/docker.exe
. - Add
C:\docker-cli
to your systemPATH
environment variable. - Create a new environment variable called
DOCKER_HOST
with the valuetcp://localhost:2375
. - Close all your Windows Terminal windows and start a new one.
- If everything works, you should be able to run
docker version
in PowerShell and see the output of the Docker Engine running inside WSL2.
Use cgroupsv2
Thanks to @spurin and his GitHub repo.
- Create a text file called
.wslconfig
in your Windows user folder (be careful with the extension, it should not be.wslconfig.txt
). - Add the following content:
[wsl2] kernelCommandLine = cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1
- Restart WSL2 from PowerShell:
wsl --shutdown
. - Open a new WSL2 shell and check if
cgroupsv2
is enabled using an ad-hoc docker image:
If you seedocker run -it --rm spurin/wsl-cgroupsv2:latest
Success: cgroup type is cgroup2fs
in the output, you are good to go.
I can hear some of you saying “What do you mean, install PowerShell?”. I had the same reaction. It turns out, the default Windows PowerShell is not the same as the new PowerShell 7. I’ll have a blog post here at some point about that. ↩︎
Thanks to this answer on AskUbuntu for the tip. ↩︎