How it works
The explanation, with examples you can run.
Seeing the VM
docker context ls# NAME DOCKER ENDPOINT# desktop-linux * unix:///Users/you/.docker/run/docker.sock docker info --format '{{.OperatingSystem}} {{.KernelVersion}} {{.Architecture}}'# Docker Desktop 6.12.54-linuxkit aarch64 docker run --rm alpine:3.22 uname -m# aarch64The kernel is the VM's (a LinuxKit build), not Darwin. The VM is managed by a virtual machine manager: on Apple silicon the default is Apple's Virtualization framework, and recent releases also offer Docker VMM, Docker's own container-optimised VMM (still beta). Settings such as CPUs, memory and disk size apply to this VM, so a container can never use more memory than the VM was given.
Files: bind mounts cross a boundary
When you bind-mount a folder from your Mac (-v "$PWD":/app), Docker Desktop shares it into the VM, by default with VirtioFS. That works well for source code, but workloads that touch thousands of small files (installing node_modules, compiling, database files) are noticeably slower than on native Linux. Common fixes:
- put dependency folders and databases in named volumes, which live inside the VM's disk;
- use Compose
develop.watchto sync changed files instead of mounting the whole tree.
Networking: three different localhosts
The VM has its own network stack. Docker Desktop forwards each published port (-p 8765:3000) to the same port on the Mac, so curl localhost:8765 works as on Linux. In the other direction, a container that needs a service on the Mac cannot use localhost (that is the container) and should use the special name host.docker.internal:
docker run --rm alpine:3.22 getent hosts host.docker.internal# 192.168.65.254 host.docker.internalFeatures that assume the container and host share one network, such as --network host, behave differently than on a Linux server, so test anything network-sensitive on Linux before shipping.
CPU architecture
On Apple silicon the VM is arm64, so it runs linux/arm64 images natively. An image that only exists for linux/amd64 needs emulation (Rosetta or QEMU, if enabled in settings). Without it, it fails:
docker run --rm --platform linux/amd64 alpine:3.22 uname -m# exec /bin/uname: exec format error (on a Desktop without amd64 emulation)Even with emulation, amd64 images are slower and occasionally behave differently. The fix is to build and pull multi-platform images (see BuildKit), so every machine, from your laptop to an amd64 server, gets a native variant.
What carries over
Everything you learn here about images, layers, networks and volumes is the same on a Linux server; only the VM boundary is extra. When something works on your Mac but not in production (or the reverse), check the three usual suspects first: file sharing, networking through the VM, and CPU architecture.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.