Skip to main content
Docker Containers On Windows Wsl2 (2026)

Setting Up Docker Containers on Windows WSL2: A 2026 Tutorial

Docker on Windows has converged on a single sensible architecture: the WSL2 backend. The old Hyper-V isolation mode still exists for edge cases, but for development work — building images, running containers, composing multi-service stacks — the WSL2 backend provides Linux-native container performance with transparent integration into your Windows workflow. The containers run inside the WSL2 lightweight VM, which means they use a real Linux kernel, support every Linux container image without translation, and perform I/O at near-native speed on the ext4 filesystem.

This guide covers Docker configuration on Windows 11 with WSL2 in 2026, including Docker Desktop versus standalone Docker Engine installation, rootless mode, compose workflows, networking behaviour, and the volume mount patterns that affect performance. If you have worked through the WSL2 GUI apps guide or the GPU acceleration guide on this site, your WSL2 environment is already configured — Docker builds on that foundation. This guide is part of the how-to section and connects to the broader Linux on Windows topic.


Docker Desktop vs standalone Docker Engine

You have two options, and the choice matters more than the Docker documentation suggests.

Docker Desktop installs a Windows application that manages the Docker daemon inside WSL2. It provides a GUI dashboard, automatic updates, Kubernetes integration, and the docker CLI available from both PowerShell and WSL2 terminals. The licensing changed in 2022 — it requires a paid subscription for organisations with more than 250 employees or more than $10 million in revenue. For individual developers and small teams, it remains free.

Standalone Docker Engine installs the Docker daemon directly inside your WSL2 distribution, exactly as you would on a regular Linux server. No GUI, no Windows integration, no licensing restrictions. You manage it with systemctl (or manually, since WSL2's init system support varies by distribution).

For most individual developers, Docker Desktop is the smoother experience. For teams that need to avoid the licensing or want identical behaviour to their Linux CI/CD servers, the standalone engine is the correct choice.


Installing Docker Desktop with WSL2

Download Docker Desktop from docker.com and run the installer. During installation, ensure "Use WSL 2 instead of Hyper-V" is selected. After installation:

  1. Open Docker Desktop settings
  2. Navigate to Resources → WSL Integration
  3. Enable integration with your preferred WSL2 distributions

Verify from a WSL2 terminal:

docker run hello-world

If this works, Docker is functional. The daemon runs inside a dedicated Docker Desktop WSL2 distribution (visible in wsl -l -v as docker-desktop), and the CLI tools are proxied into your development distributions.


Installing standalone Docker Engine

Inside your WSL2 Ubuntu distribution:

sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Start the daemon:

sudo service docker start

Add your user to the docker group to avoid needing sudo for every command:

sudo usermod -aG docker $USER

Log out and back into your WSL2 session for the group change to take effect.


Volume mounts and filesystem performance

This is where Docker on WSL2 gets nuanced, and where understanding the filesystem interop behaviour matters practically.

Docker volumes stored on the ext4 filesystem inside WSL2 perform well — comparable to native Linux Docker performance. Volumes that cross the Windows filesystem boundary through /mnt/c are dramatically slower, because every I/O operation passes through the 9P protocol translation layer between the Linux VM and the Windows host.

The practical rule: keep your project source code inside the WSL2 filesystem (/home/user/projects/, not /mnt/c/Users/user/projects/). Mount code into containers from the WSL2 path. Bind mounts from /mnt/c paths work correctly but perform 5–10x slower for I/O-heavy operations like npm install or compilation.

# Good — source lives on WSL2 ext4
volumes:
- /home/user/myapp:/app

# Slow — source lives on Windows NTFS via 9P
volumes:
- /mnt/c/Users/user/myapp:/app

If your editor runs on Windows and needs to access files inside WSL2, use the \\wsl$\ network path from Windows Explorer or configure your editor's remote/WSL extension. VS Code's WSL extension handles this seamlessly.


Docker Compose workflows

Docker Compose works identically to native Linux once Docker is running. Place your compose.yaml in a WSL2 filesystem directory and run:

docker compose up -d

For multi-service development stacks (application server, database, cache, message queue), compose on WSL2 is mature and performant. The containers share the WSL2 VM's network namespace by default, so inter-container communication uses localhost or Docker's internal DNS resolution as expected.


Networking

Containers running in Docker on WSL2 expose ports that are accessible from the Windows host. If a container publishes port 8080, you can reach it at localhost:8080 from a Windows browser. This forwarding happens automatically.

Accessing containers from other machines on the local network is less straightforward. WSL2 uses a virtual network adapter with NAT, so the container ports are not directly reachable from the LAN by default. You need to set up port forwarding from the Windows host:

netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=$(wsl hostname -I)

The WSL2 IP address can change between reboots, so this forwarding rule may need updating. For persistent LAN access, consider using WSL2's mirrored networking mode (available in recent builds) which gives the WSL2 VM the same IP as the Windows host.


Rootless Docker

For security-conscious setups, rootless Docker runs the daemon without root privileges:

dockerd-rootless-setuptool.sh install

Rootless mode avoids the security implications of adding users to the docker group (which effectively grants root-equivalent access). The trade-off is that rootless Docker cannot bind to privileged ports (below 1024) without additional configuration, and some container operations that require kernel capabilities may behave differently.

For development work, rootless Docker is a sensible default. For production-like testing that requires privileged operations, standard Docker with the group permission model is more practical.


Resource management

Docker containers running on WSL2 share the VM's resource allocation. If you have configured memory limits in .wslconfig for ML workloads, those same limits apply to Docker containers. A memory-hungry container and a training job running simultaneously in WSL2 will compete for the same pool.

Monitor resource usage from inside WSL2:

docker stats

For workloads that need guaranteed resources, use Docker's resource constraint flags:

docker run --memory=4g --cpus=2 myimage

This prevents a single container from consuming the entire WSL2 allocation and starving other processes.

Field Dispatch

Stay sharp.

New guides and security notes — straight to your inbox when they drop. No noise. No sponsorships. Just the signal.

  • Security & privacy investigations
  • Linux, WSL, and server notes
  • Web performance and dev tooling

Free. No spam. Unsubscribe anytime.