Docker on WSL2 without Docker Desktop

After January 31, 2022, Docker Desktop will require a paid subscription.
Commercial use of Docker Desktop in larger enterprises (more than 250 employees OR more than $10 million USD in annual revenue) requires a Docker Pro, Team or Business subscription for as little as $5 per user per month.
The existing Docker Free subscription has been renamed Docker Personal. Docker Desktop remains free for personal use, education, non-commercial open source projects, and small businesses (fewer than 250 employees AND less than $10M USD in annual revenue).
Source: https://www.docker.com/legal/docker-subscription-service-agreement

So, how to run Docker on WSL2 under Windows without Docker Desktop (Debian / Ubuntu)?

  • On Windows: uninstall Docker Desktop
  • On WSL2: sudo apt remove docker docker-engine docker.io containerd runc

Continue on WSL2 with the following

  1. Install pre-required packages
    • sudo apt update
    • sudo apt install --no-install-recommends apt-transport-https ca-certificates curl gnupg2
  2. Configure package 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
    • sudo apt update
  3. Install Docker
    • sudo apt install docker-ce docker-ce-cli containerd.io
  4. Add user to group
    • sudo usermod -aG docker $USER
  5. Configure dockerd
    • DOCKER_DIR=/mnt/wsl/shared-docker
    • mkdir -pm o=,ug=rwx "$DOCKER_DIR"
    • sudo chgrp docker "$DOCKER_DIR"
    • sudo mkdir /etc/docker
    • sudo <your_text_editor> /etc/docker/daemon.json

      {
         "hosts": ["unix:///mnt/wsl/shared-docker/docker.sock"]
      }


      • Note! Debian will also need the additional configuration to the same file
        • "iptables": false

Now you’re ready to launch dockerd and see if it works

  • Run command “sudo dockerd” - if the command ends with “API listen on /mnt/wsl/shared-docker/docker.sock”, things are working
  • You can perform an additional test by opening a new terminal and running

    docker -H unix:///mnt/wsl/shared-docker/docker.sock run --rm hello-world

Ok, things are working? Great!

Then it’s time to create a launch script for dockerd. There are two options, manual & automatic

  • To always run dockerd automatically
    • Add the following to .bashrc or .profile (make sure “DOCKER_DISTRO” matches your distro, you can check it by running “wsl -l -q” in Powershell)

      DOCKER_DISTRO="Ubuntu-20.04"
      DOCKER_DIR=/mnt/wsl/shared-docker
      DOCKER_SOCK="$DOCKER_DIR/docker.sock"
      export DOCKER_HOST="unix://$DOCKER_SOCK"
      if [ ! -S "$DOCKER_SOCK" ]; then
         mkdir -pm o=,ug=rwx "$DOCKER_DIR"
         sudo chgrp docker "$DOCKER_DIR"
         /mnt/c/Windows/System32/wsl.exe -d $DOCKER_DISTRO sh -c "nohup sudo -b dockerd < /dev/null > $DOCKER_DIR/dockerd.log 2>&1"
      fi
  • To manually run dockerd
    • Add the following to your .bashrc or .profile

      DOCKER_SOCK="/mnt/wsl/shared-docker/docker.sock"
      test -S "$DOCKER_SOCK" && export DOCKER_HOST="unix://$DOCKER_SOCK"

Want to go passwordless with the launching of dockerd?

All you need to do is

  • sudo visudo
  • %docker ALL=(ALL) NOPASSWD: /usr/bin/dockerd

Enable / disable BuildKit (optional)

You may end up wanting to enable/disable BuildKit depending on your use cases (basically to end up with the classic output with Docker), and the easiest way for this is to just add the following to your .bashrc or .profile

   export DOCKER_BUILDKIT=0
   export BUILDKIT_PROGRESS=plain

Adding some finishing touches

To wrap things up, you most likely will want to install docker-compose. You can start by checking up the number of the latest stable version from the Docker Compose documentation and doing the following (we’ll be using version 1.29.2 in this example)

  • COMPOSE_VERSION=1.29.2
  • sudo curl -L "https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  • sudo chmod +x /usr/local/bin/docker-compose