Back to All Cheatsheet Libraries cheatsheets

Docker for macOS

The Mac-host side of Docker: virtualization framework vs Docker VMM, Rosetta emulation, resource tuning, VirtioFS file sharing, and OrbStack/Colima as alternatives.

Docker on a Mac always runs inside a lightweight Linux VM

Containers are a Linux kernel feature — there's no such thing as a "native macOS container." Docker Desktop's entire job on a Mac is running that Linux VM efficiently and making the seams (file sharing, networking, resource limits) invisible. Nearly every Mac-specific setting and gotcha on this page traces back to that one fact. This page assumes you already know the Docker CLI/Compose/Dockerfile basics — see the general Docker cheatsheet for those.

1

Install the right build

Download the ARM64 installer for Apple Silicon (M1 and newer) or the AMD64 installer for an Intel Mac — check with uname -m if unsure (arm64 vs x86_64). Double-click Docker.dmg, drag Docker to Applications, launch it, and accept the subscription agreement on first run.

2

Or install headless from the command line

brew install --cask docker # Homebrew, still opens the GUI app on launch sudo hdiutil attach Docker.dmg sudo /Volumes/Docker/Docker.app/Contents/MacOS/install --accept-license
3

Minimum requirements

A supported macOS version (Apple's current release plus the two previous majors) and at least 4 GB of RAM — in practice, budget well beyond the minimum if you're running more than one or two containers at once.

4

Verify it's working

docker run hello-world docker context ls # confirm "desktop-linux" is the active context
Your Mac → Virtual Machine Manager (VMM) → a Linux VM → the Docker daemon → your containers

Apple Virtualization framework

The long-standing default VMM, built on Apple's own hypervisor APIs. Required if you want the Rosetta emulation option below — it isn't available under Docker VMM.

Docker VMM (Beta)

A newer, Docker-optimized VMM aimed at better container performance. VirtioFS is the only file-sharing option it supports — no gRPC FUSE fallback.

Rosetta for x86_64/amd64 emulation

A General-tab checkbox (Apple Virtualization framework only) that runs x86 binaries inside the Linux VM through Rosetta instead of QEMU — roughly 20% slower than native versus QEMU's roughly 85% slower.

--platform flag

Explicitly request an architecture per image/build: docker run --platform linux/amd64 … forces Intel emulation even when an ARM64 image also exists.

Task Command Notes
Force an Intel image on Apple Silicondocker run --platform linux/amd64 mysql:8For an image with no ARM64 build. Enable the Rosetta setting first (Virtualization tab) for meaningfully better performance than plain QEMU emulation.
Check what architecture an image supportsdocker manifest inspect mysql:8 | grep architectureConfirms whether you actually need emulation before reaching for --platform at all.
Build a multi-arch imagedocker buildx build --platform linux/amd64,linux/arm64 -t acme/app:latest --push .Ships one tag that works natively on both architectures — the right fix when you control the Dockerfile, rather than emulating forever.
Enable Rosetta emulationSettings → General → Use Rosetta for x86_64/amd64 emulation on Apple SiliconApple Virtualization framework only. Since Docker Desktop 4.3.0 the underlying Rosetta 2 install is no longer a hard requirement, though a few optional CLI tools still want it: softwareupdate --install-rosetta.

The Resources tab is where "it's slow" usually actually gets fixed

Docker Desktop → gear icon → Resources. Every setting here governs the Linux VM, not your Mac directly — raising memory here doesn't touch your Mac's actual RAM allocation for other apps beyond what the VM reserves.

Setting What it controls
CPU limitMax CPUs the VM can use. Leave headroom for macOS itself and whatever else is running — pinning it to 100% of your cores makes the whole Mac sluggish, not just Docker.
Memory limitDefaults to roughly 50% of host RAM. Raise it for memory-hungry workloads (Elasticsearch, multiple databases at once); lower it if Docker is starving other apps.
Swap1 GB default. A safety net for memory spikes, not a substitute for enough real memory allocation.
Disk usage limit / image locationCaps how much disk the VM's virtual disk can grow to, and can move that disk image file to a different volume — useful if your boot drive is small and you have a larger external/secondary drive.
File sharing: VirtioFS (default)Docker's own numbers: up to 98% faster filesystem operations than the legacy approach. The only option available under Docker VMM.
File sharing: gRPC FUSEThe older alternative, only relevant if you're on Apple Virtualization framework and hit a VirtioFS-specific compatibility issue.
Case sensitivity — the bug that only shows up in production
  • macOS's filesystem is case-insensitive by default; Linux (inside the container) is always case-sensitive. Docker enforces correct-case access through the shared mount specifically to stop this from silently working in local dev and then breaking the moment the same code runs on a real Linux server.
  • The practical rule: if import './Utils' and the real file is utils.js, fix the reference — don't rely on macOS quietly tolerating the mismatch.

Docker Desktop isn't the only way to run containers on a Mac. All three below expose a Docker-compatible socket, so your existing docker CLI and Compose files keep working — only the underlying VM and its performance characteristics change.

Tool Cost Why you'd pick it
Docker DesktopFree for individuals/small business; paid subscription required past certain company-size thresholds — check Docker's current terms.Official, most compatible, best support surface for anything Docker-branded (Docker Scout, Compose Bridge, Docker Build Cloud).
OrbStackFree tier; Pro is a paid annual subscription.Built natively for macOS on the Hypervisor framework rather than a general-purpose Linux VM — reported cold-start around 2 seconds versus Docker Desktop's ~12, and the fastest bind-mount file I/O of the three. The closest drop-in replacement.
ColimaFree and open source, no paid tier.A lightweight, scriptable CLI-only runtime on Apple's Virtualization framework — brew install colima && colima start. No GUI at all, which is exactly the point for some setups (CI runners, minimal environments, or anyone who just wants docker to work without a menu-bar app).
# Colima quickstart brew install colima docker docker-compose colima start --cpu 4 --memory 8 docker ps # works immediately — same CLI, different backend
Symptom Cause / fix
Bind-mounted volume feels painfully slowClassic Mac-host bind-mount I/O overhead, worst with tools that watch thousands of small files (node_modules, a Python venv). Try VirtioFS if not already selected, exclude heavy directories from the mount where possible, or switch to OrbStack/Colima for better raw I/O.
"exec format error" running a containerArchitecture mismatch — an amd64-only image running natively on Apple Silicon with no emulation. Add --platform linux/amd64 and ensure Rosetta emulation is enabled.
Docker Desktop won't start / spins foreverQuit fully (Activity Monitor → force-quit any lingering com.docker.* processes), then relaunch. If that fails, Docker Desktop's own "Troubleshoot → Clean / Purge data" resets the VM without uninstalling.
VPN breaks container networkingA common, long-standing interaction between corporate VPN clients and the Docker VM's virtual network — check Docker Desktop's Resources → Network tab for a VPN-compatibility toggle before assuming your Compose file is wrong.
Import works locally, fails on the real Linux serverCase-sensitivity mismatch (see the Resources tab) — a path that macOS resolved leniently that Linux never will.
Disk usage keeps growing even after removing containersDangling images/volumes/build cache, not the containers themselves — docker system df to see the breakdown, docker system prune -a --volumes to reclaim it (destructive — reads every unused image, container, and volume).
"Cannot connect to the Docker daemon" from a script/CI runnerConfirm Docker Desktop (or Colima) is actually running and the active context is correct: docker context ls, then docker context use desktop-linux if it drifted.