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
dockerinside WSL2; - configure it as a
systemdservice; - use
dockerinside 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
systemdin 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
dockergroup:sudo usermod -aG docker $USER.Override the
docker.servicefile:sudo systemctl edit dockeradding the following text[Service] ExecStart= ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sockbetween
### Anything between here and the comment below will become the new contents of the fileand
### Lines below this comment will be discardedIn 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
systemddaemon: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
keychainto make sure you WSL will not be killed when you close the last shell window2:sudo apt update && sudo apt install keychain -ysudo -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 allbefore 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.exewill be in thebuildfolder of the repository. - Create a directory under C: (or wherever you want) called
docker-cli:mkdir /mnt/c/docker-cli. - Move
docker-windows-amd64.exeto that folder:mv build/docker-windows-amd64.exe /mnt/c/docker-cli/docker.exe. - Add
C:\docker-clito your systemPATHenvironment variable. - Create a new environment variable called
DOCKER_HOSTwith 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 versionin 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
.wslconfigin 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
cgroupsv2is enabled using an ad-hoc docker image:
If you seedocker run -it --rm spurin/wsl-cgroupsv2:latestSuccess: cgroup type is cgroup2fsin 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. ↩︎