Skip to the content.

Native Docker in WSL - even in a VM, No Docker Desktop


Install WSL in a VM

We need to Enable Nested VM (Powershel on the parent host machine)

Set-VMProcessor -VMName "_FayedVM" -ExposeVirtualizationExtensions $true

How to locate the .vhdx file and disk path for your Linux distribution

(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq '<DistributionName>' }).GetValue("BasePath") + "\ext4.vhdx"

# The result will display a path looking something like %LOCALAPPDATA%\Packages\<PackageFamilyName>\LocalState\<disk>.vhdx. For example:
# C:\Users\fayed\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx

How to expand the size of your WSL 2 Virtual Hard Disk:

Steps to install Docker in WSL

Longin as root, to avoid using sudo many times

sudo -i
apt update && apt upgrade

if you faced DNS connectrviy issue:

echo -e "[network]\ngenerateResolvConf = false" | tee -a /etc/wsl.conf
unlink /etc/resolv.conf
echo nameserver | tee /etc/resolv.conf

remove old versions:

apt remove docker docker-engine containerd runc

Install dependencies

apt install --no-install-recommends apt-transport-https ca-certificates curl gnupg2 -y

switch to legacy iptables

update-alternatives --config iptables
# And select [ iptables-legacy ]

Ubuntu package repository configuration

cat /etc/os-release

# note the ID (ubuntu in my case) and VERSION_CODENAME (jammy in my case) and use them in the bellow lines:

curl -fsSL | tee /etc/apt/trusted.gpg.d/docker.asc
echo "deb [arch=amd64] jammy stable" | tee /etc/apt/sources.list.d/docker.list
apt update

Install Docker

apt install docker-ce docker-ce-cli -y

update docker-compose to latest version (

curl -L "$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose
docker-compose --version

Create non-root-user, create home directory, and set default shell to bash (you can change it later with chsh command):

useradd -m -s /bin/bash [UserName]

set password and add the user to sudo and docker groups:

passwd [UserName]
usermod -aG sudo [UserName]
usermod -aG docker [UserName]

Passwordless launch of dockerd:

su [UserName]
echo "`whoami` ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/`whoami` && sudo chmod 0440 /etc/sudoers.d/`whoami`


docker run --rm hello-world

Auto Start Docker:

echo 'sudo service docker start' >> ~/.profile
# OR:

echo '# Start Docker daemon automatically when logging in if not running.' >> ~/.bashrc
echo 'RUNNING=`ps aux | grep dockerd | grep -v grep`' >> ~/.bashrc
echo 'if [ -z "$RUNNING" ]; then' >> ~/.bashrc
echo '    sudo dockerd > /dev/null 2>&1 &' >> ~/.bashrc
echo '    disown' >> ~/.bashrc
echo 'fi' >> ~/.bashrc

change the WSL default login user, replace USER_NAME with the desired user name:

echo -e "[user]\ndefault=USER_NAME" >> /etc/wsl.conf

Call WSL executable from Windows

if you named this file dig.bat it will call the dig command from Linux in your WSL

@echo off
SETLOCAL EnableExtensions
SETLOCAL DisableDelayedExpansion
set v_params=%*
set v_params=%v_params:\=/%
set v_params=%v_params:c:=/mnt/c%
C:\Windows\system32\wsl.exe -d %DOCKER_DISTRO% %~n0 %v_params%

Calling Docker from Windows PowerShell ;)

Open your PowerShell profile:

notepad $profile

# %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Then Add the following:

function docker {
    wsl -d $DOCKER_DISTRO docker @Args
function docker-compose {
    wsl -d $DOCKER_DISTRO docker-compose @Args

Calling Docker from Windows Command Prompt

create 2 batch files docker.bat, docker-compose.bat and add them to any location included in your %PATH%

for docker.bat, add the following:

@echo off
wsl -d %DOCKER_DISTRO% docker %*

for docker-compose.bat, add the following:

@echo off
wsl -d %DOCKER_DISTRO% docker-compose %*

VSCode Docker extention

Although the above solutions works well from Windows PowerShell and Commmand Prombet, they don’t work the VS Code Docker Extenstion but there is a solution ;)

Downmload these shims for both Dokcer and Docker-Compose and add them to your path

VSCode DevContainer

the solution that worked for me is to open my code folder from WSL, then open in DevContainer (better to have your code in a native Linux path like /code/.. rather than a mounted Windows path like /mnt/c/...)