skip to content

Where does the Docker engine actually run when you use Docker Desktop on macOS or Windows?

level: juniorimportance: must knowfreq 64%

answer

  1. Containers need a kernel you do not have
  2. Something has to supply Linux
  3. The CLI is only a client
  4. dockerd lives on the other side
  5. WSL 2 distribution on Windows

basics

~20 s

Docker Desktop boots a small Linux virtual machine and runs dockerd inside it. The docker command you type on macOS or Windows is only a client talking to that daemon, so every Linux container is a process inside the VM.

solid answer

~50 s

A Linux container is an ordinary Linux process isolated with kernel namespaces and cgroups, and neither the macOS kernel nor the Windows NT kernel provides those. So Docker Desktop boots a minimal Linux VM — on macOS through the operating system's virtualization framework, on Windows through a Docker-managed WSL 2 distribution — and runs `dockerd` and `containerd` inside it. The `docker` CLI on your host is a thin client over the engine's REST API and connects to that VM. Everything the engine owns lives there: image layers, named volumes, `/var/lib/docker`, the `docker0` bridge and container IPs. Your host only contributes what Desktop bridges across the boundary — published ports forwarded into the VM, shared host directories exposed as bind mounts, and a CPU and memory budget the VM may use. Almost every "works on my laptop" surprise is that boundary showing through.

code

bash · 2 lines
bash
docker info --format '{{.OperatingSystem}} | {{.KernelVersion}} | {{.MemTotal}}'
docker context ls

go deeper

for a junior

Be ready to say plainly that Docker Desktop runs a Linux VM and that your docker command is a client talking to a daemon inside it. Knowing that containers need a Linux kernel is the whole point of the question.

for a middle

An interviewer expects you to draw the boundary: which pieces (dockerd, containerd, image layers, volumes, container networks) sit inside the VM and which (the CLI, your source tree, published-port listeners) sit on the host, and how the CLI reaches the daemon.

for a senior

Show that you predict the symptoms from the architecture — unreachable container IPs, slow shared directories, resource ceilings, arm64-by-default builds — instead of treating each as a separate piece of trivia to memorise.

for a principal

Own the consequence for the team: the laptop is not the production runtime, so decide deliberately what has to be verified on a Linux host or in CI rather than on a developer machine, and what local parity is worth paying for.

### Why there is a VM at all Containers are not a portable technology in the way images make them look. An image is a portable artefact — a stack of tar layers plus a config blob, defined by the OCI image spec — but *running* one requires a Linux kernel. The isolation a container gets comes from kernel features: PID, mount, network, UTS, IPC and user namespaces for what the process can see, and cgroups for what it can consume. Those are Linux kernel interfaces. The XNU kernel on macOS and the NT kernel on Windows do not implement them, so there is nothing on a Mac for `runc` to call. Docker Desktop solves this the only way it can: it ships a Linux system and runs it in a virtual machine on your laptop, then runs the engine inside that Linux system. On macOS the VM is started through the operating system's own virtualization support (Desktop has used more than one virtual-machine manager over its life, and the choice is exposed as a setting). On Windows the default is the WSL 2 backend, where Desktop installs and manages its own WSL distribution and runs the engine there; WSL 2 is itself a lightweight VM with a real Linux kernel, so the shape is the same. ### What is on which side of the boundary Inside the VM: `dockerd`, `containerd`, the shims and `runc`, `/var/lib/docker` with all image layers and named volumes, the default `docker0` bridge and every user-defined network, container IP addresses, the Linux kernel whose version `docker info` reports, and the memory and CPU budget the VM was given. On your host: the `docker` and `docker compose` executables, the Desktop application and its background services, your source tree, and the ports Desktop listens on so that traffic can be forwarded inward. The CLI is deliberately thin. It speaks the engine REST API — `GET /containers/json`, `POST /images/create` and so on — over a socket. Desktop exposes a Unix socket on the host side (on macOS, `/var/run/docker.sock` is typically a symlink into the user's `~/.docker` directory) and proxies it into the VM, where `dockerd` is listening. This is exactly the same API the CLI would use against a Linux daemon on the same machine or a remote one; only the transport differs. That is why `docker context ls` shows the Desktop endpoint as just another context, and why `docker info` reports the VM's kernel version, OS type and total memory rather than anything about your Mac. ### The consequences you will actually trip over **Storage.** There is no `/var/lib/docker` on your Mac to inspect. Images and volumes live in the VM, inside a single large virtual-disk file that Desktop manages. You interact with them only through the engine — `docker image ls`, `docker volume inspect` — not with Finder or Explorer. **Networking.** "The host", from a container's point of view, is the VM. Container IP addresses are addresses on a bridge inside the VM, and your host OS has no route to them. Reaching a container from a browser on your laptop means publishing a port so that Desktop forwards it inward. **Files.** A bind mount does not hand the container a local directory; it hands it a directory shared across the VM boundary by a file-sharing protocol. That works, and it is slower than a native mount. **Resources.** A container cannot use more CPU or memory than the VM has, no matter how much the laptop has. The VM's budget is a Desktop (or WSL) setting. **Architecture.** The VM runs the host machine's CPU architecture — arm64 on Apple Silicon, amd64 on a typical PC. An image built with no further instruction is built for that architecture, which is why an image built casually on an Apple Silicon Mac can fail to start on an amd64 server. ### How to say this in an interview The compact version is three sentences: containers need a Linux kernel; macOS and Windows do not have one, so Desktop runs a Linux VM; the CLI is a client and the daemon, the images, the networks and the container processes are all on the other side of that boundary. Then name one consequence — networking, file sharing or resource limits — to show you have actually hit it rather than only read about it.

  • How does the docker CLI on macOS actually reach dockerd inside the VM?
    Desktop exposes a Unix socket on the host side and proxies it into the VM, where `dockerd` listens. The CLI then speaks the ordinary engine REST API over it — the same API it would use against a Linux daemon — so nothing about the commands changes. `docker context ls` shows which endpoint is in use, and `docker info` confirms you are talking to the VM by reporting its Linux kernel version and total memory.
  • Does anything change about image builds because the daemon is inside a VM?
    Yes. The build context is packaged on the host and sent across the boundary to the builder in the VM, so a large or unfiltered directory costs a transfer before the first instruction runs — a good `.dockerignore` matters more here than on Linux. The build cache also lives in the VM's disk, and the default build platform is the VM's architecture, which on Apple Silicon is arm64.
  • If images live in the VM, why can you still `docker run -v $PWD:/app` a directory from your Mac?
    Because Desktop shares selected host directories into the VM over a file-sharing protocol and the engine bind-mounts the shared path into the container. The path you type is translated across the boundary rather than being a local kernel bind mount, which is also why only directories Desktop is configured to share are available and why the mount is slower than on Linux.

Docker Desktop is less like installing an engine on your laptop and more like plugging a cable into a small Linux machine that happens to be sitting inside it: your keyboard is on one side, the workshop is on the other, and everything has to be handed through the hatch.

saying these in an interview costs you the question

  • Claims Docker runs natively on macOS
  • Thinks Docker Desktop is just a GUI over a local daemon
  • Expects /var/lib/docker to exist on the Mac
  • Says containers use the macOS or NT kernel
  • Assumes the WSL 2 backend means Windows containers
  • Believes container IPs are laptop network addresses

context