A container is not a small virtual machine - it is a Linux process that borrows the host's Linux kernel. Windows does not have one. WSL 2 quietly supplies a real Linux kernel in a lightweight utility VM, and that single fact is the whole reason Docker on Windows works the way it does.
People ask why Docker Desktop insists on WSL 2 when WSL 1 already 'runs Linux'. The short answer: WSL 1 translated Linux calls into Windows calls, and a translation layer is not a kernel. Docker's engine needs real kernel features - namespaces, cgroups, overlay filesystems. WSL 2 runs an actual Microsoft-maintained Linux kernel, so the engine runs natively. Here is the honest picture, including the small performance tax you pay for it.
A container shares the host kernel. The isolation, resource limits and layered filesystem that make Docker work are Linux kernel features. That is why every Linux container on any platform is, underneath, talking to a Linux kernel somewhere.
WSL 1 worked by translating each Linux system call into a Windows equivalent. Clever, but translation has gaps: some kernel behaviour simply has no Windows twin, and Docker's engine hit those gaps immediately.
WSL 2 changed the architecture completely: a real Linux kernel running in a very light virtual machine managed by Windows. Startup is fast, memory is given back when idle (mostly), and because the kernel is real, Linux software - including the Docker engine - behaves exactly as it does on a Linux PC.
When you install Docker Desktop with the WSL 2 backend, the engine (dockerd) runs inside a special hidden WSL distribution managed by Docker itself. Your own Ubuntu distro then gets the docker command connected to that engine if you enable WSL Integration in Docker Desktop settings.
This is also why docker ps from inside Ubuntu and from PowerShell show the same containers - there is only one engine.
Memory: the WSL 2 VM grows as containers need RAM and does not always shrink back immediately. You can cap it with the .wslconfig file - there is a page in this set on exactly that.
Cross-filesystem speed: containers reading files from /mnt/c (your Windows drives) are much slower than reading files stored inside the Linux filesystem. Keep the project inside Ubuntu for real work.
One more kernel to update: wsl --update keeps the kernel current, and an out-of-date kernel is a common cause of Docker start failures.
Watch the video to see WSL 2 and Docker Desktop set up together, in the right order, from a clean machine.
▶️ Watch Full VideoOn Windows Pro and Enterprise there is an older Hyper-V backend, but WSL 2 is the recommended backend for almost everyone - it starts faster, uses resources dynamically and works on Home editions too. This set covers the WSL 2 route only.
It is a lightweight utility VM running a real Linux kernel, managed automatically by Windows. You do not create, snapshot or maintain it like a normal VM - you just use the distros inside it.
Files reached through /mnt/c cross the Windows-Linux boundary on every operation, which is slow for the thousands of small files in a typical project. Move the project into the WSL filesystem (for example your Ubuntu home folder) and the same container becomes much faster.