Run Docker on Windows without Docker Desktop

I had an old laptop where I installed Docker Desktop. While I mainly used the command line, I still experienced all the downsides that come with it, it made my laptop super slow and added unnecessary overhead. Today, when I wanted to install Docker on a new Windows machine, those past memories hit me. So, I decided to install just the CLI without the slow UI. I’ll share my process with you in this tutorial.

So, without further ado, let’s learn how to install and use Docker on Windows without Docker Desktop!

Prerequisites

  • WSL2 (If you don’t have it installed, open PowerShell as Administrator and run wsl --install)
  • Administrator access on your Windows machine

Step 1: Install Docker in WSL

First, we need to install Docker on WSL Linux distribution. Open your WSL terminal and follow the instructions here, assuming you’re using Ubuntu:

Step 2: Install Docker CLI on Windows

Since there’s no official Windows release for the Docker CLI alone, we’ll need to build it ourselves or use a pre-built binary. Here are two options:

Option A: Build it yourself (Advanced)

  1. Get a temporary VPS with Docker installed.
  2. Clone the Docker CLI repository: git clone https://github.com/docker/cli.git
  3. Build it using: docker buildx bake --set binary.platform=windows/amd64
  4. Rename the resulting docker-windows-amd64.exe to docker.exe

Option B: Download pre-built binary (Easier)

  1. Download from https://github.com/StefanScherer/docker-cli-builder/releases

After obtaining the docker.exe file, create a new folder at C:\Users\YourUsername\Docker and place the file there. Then, add this folder to your Windows PATH environment variable.

Step 3: Configure Docker Daemon in WSL

Now, we need to configure the Docker daemon in WSL to listen on a TCP port. In your WSL terminal:

sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json

Add the following content to the file:

{
  "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}

Step 4: Create a Systemd Override for Docker

We need to tell systemd to use our custom configuration:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf

Add the following content:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --config-file /etc/docker/daemon.json

Step 5: Restart Docker in WSL

Apply the changes by reloading systemd and restarting Docker:

sudo systemctl daemon-reload
sudo service docker restart

Step 6: Configure Docker CLI on Windows

Create or edit the file %USERPROFILE%\.docker\config.json (typically C:\Users\YourUsername\.docker\config.json) and add:

{
    "host": "tcp://localhost:2375"
}

Step 7: Set Windows Environment Variable

Open PowerShell as Administrator and run:

[Environment]::SetEnvironmentVariable("DOCKER_HOST", "tcp://localhost:2375", "User")

Step 8: Configure Windows Firewall

We need to allow the connection through the Windows Firewall. In PowerShell as Administrator, run:

New-NetFirewallRule -DisplayName "WSL 2 Docker" -Direction Inbound -LocalPort 2375 -Action Allow -Protocol TCP
New-NetFirewallRule -DisplayName "WSL 2 Docker Outbound" -Direction Outbound -LocalPort 2375 -Action Allow -Protocol TCP

Step 9: Restart and Test

Restart your WSL instance and open a new PowerShell window to ensure all changes are reflected. Then, test your Docker installation:

docker version
docker run hello-world

If everything is set up correctly, you should see the Docker version information and the “Hello from Docker!” message.


Installing Docker Compose (Optional)

Now that Docker is running in WSL, let’s add Docker Compose for managing multi-container applications. The modern Docker installation includes Compose as a plugin, which uses the command docker compose (with a space) rather than the older docker-compose format.

First, install the Docker Compose plugin in your WSL environment:

sudo apt update
sudo apt install docker-compose-plugin

Verify the installation:

docker compose version

This should display something like Docker Compose version v2.39.1. For most modern projects, this is all you need. You can now use docker compose up, docker compose down, and other commands with the space syntax.

Creating Compatibility for Legacy Tools (Optional)

Recently, I encountered a package that specifically required docker-compose (with hyphen) as a dependency. Some older scripts, tools, and documentation still expect this format. If you run into similar compatibility requirements, here’s how to create a wrapper that bridges both formats.

In WSL:

Create a wrapper script that translates the hyphenated command to the modern format:

  1. Open your WSL terminal
  2. Create the wrapper script: sudo nano /usr/local/bin/docker-compose
  3. Add this content: #!/bin/sh docker compose --compatibility "$@"
  4. Save and exit (Ctrl+X, then Y, then Enter)
  5. Make it executable: sudo chmod +x /usr/local/bin/docker-compose

The --compatibility flag helps when working with older compose file formats by converting certain version 1 behaviors to work with version 2.

In Windows:

If you also need the hyphenated command to work from Windows Command Prompt or PowerShell:

  1. Create a batch file called docker-compose.bat in a directory that’s in your PATH (or create C:\bin\ and add it to PATH)
  2. Add this content: @echo off wsl docker compose --compatibility %*
  3. If you created a new directory, add it to your Windows PATH through System Properties → Environment Variables
  4. Restart your terminal

Testing Docker Compose

Test your setup with a simple compose file. Create a file named docker-compose.yml:

version: '3'
services:
  hello:
    image: hello-world

Then run:

# Using the modern syntax
docker compose up

# Or if you created the compatibility wrapper
docker-compose up

Both commands should pull and run the hello-world image successfully.

Note: Unless you have specific tools requiring the hyphenated format, stick with docker compose (with space) as it’s the current standard. The compatibility wrapper is just a convenience for edge cases where legacy support is needed.


And there you have it! You’ve successfully installed Docker on Windows without Docker Desktop. This setup gives you a lightweight Docker environment that doesn’t slow down your system like Docker Desktop can.