Install Docker in WSL 2 without Docker Desktop
It's really fast and only requires a few lines of shell scripting. You won't need to run systemd inside of WSL 2 either.
Prefer video? Here’s a recorded version of this tip on YouTube. Besides going over the steps below it covers the “why” and the pros / cons of doing this.
This post covers doing this on Ubuntu 22.04 and 24.04 but it should work with any distro that supports running Docker. I say “should” because I didn’t personally try every single distro but there’s nothing about this that would hint it won’t work on other distros.
You’ll get the same conveniences of Docker Desktop such as being able to access
localhost
in your Windows browser of choice to access any web services you
run in Docker since this feature is native to WSL 2. Volumes are also lightning
fast (comparable to native Linux).
You’ll also have options to run Kubernetes directly in WSL 2 if you choose to use KinD or any other tool that lets you run a Kubernetes cluster without Docker Desktop.
Step 1: Uninstall Docker Desktop
Since we’re installing Docker directly inside of WSL 2 you won’t need Docker Desktop installed to make this work.
If you previously had Docker Desktop installed you’ll also need to delete a paths.
On my machine it added these 2 paths in ~/.docker
within my WSL 2 instance,
you can delete them:
lrwxrwxrwx 1 nick nick 30 Sep 16 2020 contexts -> /c/Users/Nick/.docker/contexts
lrwxrwxrwx 1 nick nick 35 Aug 21 17:24 features.json -> /c/Users/Nick/.docker/features.json
Additionally, you’ll likely need to sudo rm -rf /var/run/docker*
since
Docker Desktop adds various pid files there that will conflict with Docker
starting directly from within WSL.
Lastly there’s a number of CLI plugins that get added with symlinks:
$ ls -la /usr/local/lib/docker/cli-plugins
docker-ai -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-ai
docker-buildx -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-buildx
docker-cloud -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-cloud
docker-compose -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-compose
docker-debug -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-debug
docker-desktop -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-desktop
docker-dev -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-dev
docker-extension -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-extension
docker-init -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-init
docker-sbom -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-sbom
docker-scout -> /wsl/docker-desktop/cli-tools/usr/local/lib/docker/cli-plugins/docker-scout
You can delete them with: sudo rm /usr/local/lib/docker/cli-plugins/docker-*
Once all of the above is complete you’ll want to restart WSL by closing your
Microsoft Terminal and running wsl.exe --shutdown
from PowerShell, then open
up WSL.
Step 2: Install Docker / Docker Compose v2 in WSL 2
Here’s the condensed version for Ubuntu and Debian based distros:
# Install Docker, you can ignore the warning from Docker about using WSL
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to the Docker group
sudo usermod -aG docker $USER
# Sanity check that both tools were installed successfully
docker --version
docker compose version
If you’re using a different distro it’s very similar. Docker has docs for the steps above. These steps came from official Linux installation guides:
- https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script
- https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user
- https://docs.docker.com/compose/install/linux/
Step 3: Ensure the Docker Service Runs in WSL 2
At the time of this post systemd isn’t started inside of WSL 2 by default.
We won’t need it but if you decide to enable systemd with newer versions of WSL 2 then you can skip this entire step as long as you’re ok with the limitations of running systemd in WSL 2 such as it taking ~2 minutes to start (I don’t enable systemd).
All you have to do is drop this into your ~/.profile
,
.zprofile
or equivalent file:
if grep -q "\-WSL2" /proc/version > /dev/null 2>&1; then
if service docker status 2>&1 | grep -q "is not running"; then
wsl.exe --distribution "${WSL_DISTRO_NAME}" --user root \
--exec /usr/sbin/service docker start > /dev/null 2>&1
fi
fi
The idea here is the Docker service will get started if it’s not already running. The first time this runs it’ll hang your terminal for a few seconds. However, even if you close your terminal the next time you open it, it will open instantly since Docker will already be running. Closing your terminal will not stop Docker, only rebooting Windows or fully shutting down WSL will.
You can run ps aux | grep docker
to see the Docker daemon running:
root 8899 ... /usr/bin/dockerd -p /var/run/docker.pid
root 8908 ... containerd --config /var/run/docker/containerd/containerd.toml --log-level info
After opening a new terminal you should now be able to run docker run hello-world
successfully without sudo
. By the way, I have a bunch of open
source web app examples on
GitHub if you
want to explore more in depth examples of using Docker.
As a reminder, WSL 2 still has issues around disk space and memory not being reclaimed. This would be an issue with or without Docker Desktop. This post goes over how to keep your memory and disk space in check.
Also if you’re coming from Docker Desktop and want to investigate your images
and volumes on disk you can access them in cd /var/lib/docker
. You’ll need to
be the root user. This is the default spot where Docker saves files on Linux.
# Demo Video
Timestamps
- 0:22 – Everything runs smoothly with this set up
- 0:53 – Why I ended up switching away from Docker Desktop
- 3:18 – Switching away has nothing to do with Docker Desktop license costs
- 3:56 – Why you might want to continue using Docker desktop
- 6:01 – You can still run a Kubernetes cluster locally if you want
- 7:09 – Following the Docker Linux install guides
- 8:25 – Adding your WSL 2 user to the Docker group to run Docker without sudo
- 9:44 – Install Docker Compose v2 with the Docker plugin
- 10:44 – Now we need to run the Docker service within WSL 2
- 11:19 – A tiny bit of shell scripting to ensure Docker is started
- 15:43 – How are you running Docker within WSL 2?
Have you run Docker like this? Let me know in the comments below!