Docker Desktop is installed, the whale is in the tray, and docker run works. What is actually running? This part answers that with the commands themselves, on a Windows 11 PC with Docker Desktop 4.95.0: a Windows client talking through a named pipe to a Linux engine inside a WSL distribution, a 30 GB virtual disk where every image and volume lives, and a settings file that is shorter than you expect. Every line quoted here was printed on this machine.

Steps in this part
  1. docker version: read the two halves, Client and Server, and their OS/Arch lines
  2. docker info: find Operating System, Kernel Version, Name and Docker Root Dir
  3. wsl -l -v: the docker-desktop distribution is the engine's home
  4. docker run --rm hello-world, then once without --rm; docker ps -a and docker rm by id
  5. docker images and docker system df: where the gigabytes are
  6. Find docker_data.vhdx under %LOCALAPPDATA%\Docker\wsl and compare its size with the totals
  7. docker run --rm alpine uname -a next to wsl -- uname -a: one kernel

Two programs: a Windows client and a Linux engine

docker version prints two halves. The client half says OS/Arch: windows/amd64 and Context: desktop-linux; the server half says Server: Docker Desktop 4.95.0 (242831) and, for the engine, OS/Arch: linux/amd64. The command you type is a Windows program; the thing that runs your containers is a Linux program, and they talk over a named pipe. docker context ls shows the pipe: the active context desktop-linux has the endpoint npipe:////./pipe/dockerDesktopLinuxEngine.

The engine lives in a WSL distribution

  NAME              STATE           VERSION
* Ubuntu-24.04      Stopped         2
  docker-desktop    Running         2

That second row is Docker Desktop's own distribution, and Docker's documentation says so: "Docker Desktop runs inside its own docker-desktop WSL distribution, isolated from other distributions in the same way any two WSL distributions are isolated from each other." docker info confirms it from the other side:

 Operating System: Docker Desktop
 OSType: linux
 Kernel Version: 6.18.33.2-microsoft-standard-WSL2
 Name: docker-desktop
 Docker Root Dir: /var/lib/docker
 CPUs: 24
 Total Memory: 15.5GiB

The root directory is a Linux path inside that distribution, not a folder you can open in Explorer. The engine sees all 24 logical processors of this PC and about half of its 31.77 GiB of RAM, which is the WSL 2 default, and nothing on this PC changed it: there is no .wslconfig in the user profile, and Docker's settings file holds no memory or CPU key at all. One more line worth knowing: Storage Driver: overlayfs with the containerd image store, which is why docker images below looks different from older tutorials.

The first container

docker run --rm hello-world pulled a 25.9 kB image and printed its message, 5.4 seconds in all; the same command without --rm ran in 0.6 seconds and left something behind. docker ps did not list it, because the container had already exited; docker ps -a did (other rows left out):

CONTAINER ID   IMAGE                    COMMAND                  CREATED                  STATUS                              PORTS                                           NAMES
49075b8f78f8   hello-world              "/hello"                 Less than a second ago   Exited (0) Less than a second ago                                                   vibrant_bohr

Read the columns once and you have most of Part 2. The id is the first twelve characters of the container's identity. IMAGE is what it was created from and COMMAND is the program it ran. STATUS says Exited (0), where 0 is the program's exit code. PORTS is empty here; a database container shows 0.0.0.0:15852->5432/tcp, host port to container port. NAMES is vibrant_bohr, a random name because no --name was given. docker rm 49075b8f78f8 printed the id back and the row was gone.

Where the images and the data actually are

Engine 29.8 prints docker images with new columns:

hello-world:latest   11a3eb1597e8   25.9kB   9.49kB

DISK USAGE is the unpacked size and CONTENT SIZE the compressed download; the SDK image, for comparison, is 1.25 GB unpacked from a 325 MB download. docker system df adds up everything on this PC at that moment, other projects included:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          13        4         6.645GB   4.351GB (65%)
Containers      5         2         90.11kB   49.15kB (54%)
Local Volumes   15        4         1.207GB   980.7MB (81%)
Build Cache     361       0         21.91GB   9.556GB

The build cache is the largest item, bigger than every image together; Part 8 is about that. All of it sits in one file. Under %LOCALAPPDATA%\Docker\wsl there are two virtual disks:

\Docker\wsl\disk\docker_data.vhdx 29.71
\Docker\wsl\main\ext4.vhdx         0.09

The first is the engine's data disk, 29.71 GB in gigabytes of file, and the sum of the three system df sizes is 29.76 GB. Its timestamp moved to the second a container ran. Inside a container, df -h / reports an overlay filesystem of about 1 TB with 26.6 G used: the file grows as you pull and build, up to that limit, and does not shrink on its own. The 96 MiB disk is the distribution's own system. The documentation's sentence: "By default, Docker Desktop stores the data for the WSL 2 engine at C:\Users\[USERNAME]\AppData\Local\Docker\wsl."

What the Settings change, and what they do not

%APPDATA%\Docker\settings-store.json on this PC is 314 bytes and ten keys, among them AutoStart false, UseContainerdSnapshotter true and a licence version. It stores only values that differ from the defaults, and there is no key for memory, CPUs, swap, disk size or file sharing. The settings documentation explains why: those limits are marked for Mac, Linux and Windows with Hyper-V, and "In WSL 2 mode, configure memory, CPU, and swap limits on the WSL 2 utility VM", which means a .wslconfig file in your profile, not a Docker setting. The one engine setting that exists here, %USERPROFILE%\.docker\daemon.json, keeps the builder's garbage collection at 20 GB. And AutoStart false means that after a reboot there is no engine until you open Docker Desktop, which is the "cannot find the file specified" error every Windows developer meets once.

WSL integration, and the message when it is off

Docker's documentation says the integration "is enabled on the default WSL distribution, which is Ubuntu". On this PC it was not, and running docker inside Ubuntu-24.04 printed this:

The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.

The interesting part is that something answered at all. WSL appends the Windows PATH to the Linux one, so which docker inside Ubuntu finds a Docker shell script under /mnt/c/Program Files/Docker/Docker/resources/bin/. That script checks the kernel name: under WSL 2 it runs the integrated client in /usr/bin if the integration installed one, and prints the message above if not; outside WSL it runs docker.exe, which is how Git Bash gets a working docker command. Turning the integration on is a checkbox under Settings, Resources, WSL integration; it was not changed for this series, and nothing in the eight parts needs it, because every command runs from Windows.

One kernel, two user spaces

Linux cc78b115729a 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 18 21:54:43 UTC 2026 x86_64 Linux

That is uname -a inside an Alpine container. uname -a inside Ubuntu-24.04 printed the same release and the same build stamp, because, in the documentation's words, "WSL 2 lets multiple Linux distributions run side-by-side on a single shared kernel." Only the user space differs: Alpine 3.24 in the container, Ubuntu 24.04 in the distribution. That is the model for the rest of the series: containers are processes on the WSL 2 kernel, the engine is a Linux program in its own distribution, and the Windows side is a client plus a very large file.

What this means for the next parts: file paths you hand to a container cross from Windows into that Linux world (Part 3), published ports are forwarded by Desktop's proxy rather than bound by your container (Part 4), and the disk you clean in Part 8 is docker_data.vhdx.

Frequently asked

Does Docker Desktop on Windows run Linux containers?
Yes. The docker command is a Windows program, but the engine it talks to is a Linux program running inside Docker Desktop's own WSL 2 distribution, named docker-desktop, which shares the WSL 2 kernel with any other distribution on the PC. docker info reports OSType linux and the WSL kernel version, and a container's uname -a prints the same kernel as Ubuntu in WSL.
Where does Docker Desktop store images and volumes on Windows?
In one growing virtual disk, docker_data.vhdx under %LOCALAPPDATA%\Docker\wsl\disk. On this PC it was 29.71 GB, matching the totals of docker system df: images, volumes and the build cache together. Inside the engine the path is /var/lib/docker, which is not a Windows folder; the vhdx grows as you pull and build and does not shrink by itself.
Why does docker say the command could not be found in this WSL 2 distro?
WSL integration is off for that distribution. Inside WSL the docker command found on the Windows PATH is a Docker shell script that runs the integrated Linux client when the integration is enabled and prints that message when it is not. Enable the distribution under Settings, Resources, WSL integration, or run docker from Windows, where the same script runs docker.exe.

Next: Part 2, containers: run, look inside, stop and remove, including why docker exec -it fails from Git Bash and what docker stop does to a database.