🚀 Executive Summary
TL;DR: Docker containers do not run natively on macOS due to fundamental kernel differences, instead relying on a hidden Linux Virtual Machine (VM) which often leads to performance bottlenecks, particularly with file I/O. Modern solutions like OrbStack and Colima leverage Apple’s efficient Virtualization.framework to significantly improve VM performance, while Apple’s own ‘containers’ are a distinct macOS sandboxing technology for native processes, not a replacement for Linux-based Docker.
🎯 Key Takeaways
- Docker containers fundamentally depend on Linux kernel features like cgroups and namespaces, making them incompatible with macOS’s Darwin/XNU kernel for direct execution.
- Docker Desktop for Mac operates by running a lightweight Linux Virtual Machine (VM) in the background, which introduces overhead for file sharing (e.g., virtiofs) between macOS (APFS) and the VM (ext4), impacting performance.
- Apple’s Virtualization.framework on Apple Silicon enables highly efficient Linux VMs, leading to faster Docker alternatives like OrbStack and Colima, distinct from Apple’s native ‘containers’ which are a macOS sandboxing technology for native applications, not for running Linux Docker images.
Docker on macOS isn’t magic; it runs inside a Linux Virtual Machine due to kernel differences. We’ll demystify this setup, explore how Apple’s native virtualization is changing the game, and clarify what Apple’s own “containers” are actually for.
Docker on a Mac: Decoding the VM Magic and Apple’s New Game
I remember a few months back, one of our sharpest junior engineers, Sarah, was pulling her hair out. “Darian,” she said, “my Docker build is fast, but the container runs like it’s wading through molasses. And why can’t I mount /Users/sarah/dev/project directly without Docker Desktop doing some weird magic?” Her Mac was a beast—a new M2 Max—so hardware wasn’t the issue. The problem was a fundamental misunderstanding, one that costs developers hours of frustration: Docker doesn’t *really* run on macOS. It runs *on top* of macOS, inside a tiny Linux world, and that changes everything.
The “Why”: It’s All About the Kernel
Let’s get the core truth out of the way first. Docker containers, at their heart, are a set of Linux kernel features. Technologies like cgroups (for resource limiting) and namespaces (for process isolation) are baked deep into the Linux kernel. They allow a single Linux OS to run multiple isolated processes that *think* they have the whole machine to themselves.
macOS, however, runs on the Darwin/XNU kernel. It’s a fantastic piece of engineering, but it’s not Linux. It doesn’t have cgroups or the same kind of namespaces. Trying to run a standard Linux container directly on the macOS kernel is like trying to play a Blu-ray disc in a cassette player. The hardware is there, but the underlying format is fundamentally incompatible.
So, how do we solve this? We cheat. We run Linux.
Solution 1: The Classic – The Docker Desktop Linux VM
For years, this has been the standard-bearer. When you install and run Docker Desktop for Mac, it’s not just installing a command-line tool. It’s installing and managing a lightweight, stripped-down Linux Virtual Machine (VM) in the background.
Here’s the chain of command:
- You type
docker run nginxin your macOS Terminal. - The
dockerCLI on your Mac (which is just a client) connects to the Docker Daemon. - …but that Docker Daemon isn’t running on macOS. It’s running inside the hidden Linux VM.
- The daemon inside the VM pulls the nginx image and runs the container within its own Linux environment.
This is why Sarah’s file mounts were weird. Docker Desktop has to set up a file-sharing mechanism (like virtiofs) between the macOS filesystem (APFS) and the VM’s filesystem (ext4). This translation layer adds overhead, which was the source of her performance slowdown, especially on projects with thousands of small files (looking at you, node_modules).
Darian’s Take: Docker Desktop is a brilliant piece of “it just works” engineering. It handles networking, file sharing, and the whole VM lifecycle. But convenience comes at the cost of performance and resources. It’s a heavy solution, and knowing there’s a VM underneath is the key to debugging weird performance issues.
Solution 2: The Modern Way – Tapping into Apple’s Virtualization.framework
With Apple Silicon (M1/M2/M3 chips), Apple gave us a gift: the Virtualization.framework. This is a high-level API for creating and managing VMs on macOS with incredible efficiency. It’s lightweight, fast, and leverages the hardware virtualization features of Apple’s own chips. It’s a game-changer.
While Docker Desktop now uses this framework under the hood, it’s also enabled a new generation of lighter, faster, and more CLI-friendly alternatives. My two favorites are:
- OrbStack: Incredibly fast, low-CPU usage, and a fantastic user experience. It feels like what Docker Desktop should have been. It boots its Linux VM in seconds and the filesystem performance is phenomenal.
- Colima: A great open-source, CLI-first option. It stands for “Containers on Linux on macOS”. It’s highly configurable and perfect for engineers who live in the terminal and want to avoid a heavy GUI application.
Switching to one of these still involves running a Linux VM, but because they use Apple’s framework so efficiently, the performance penalty is drastically reduced. It feels much closer to a native experience.
To get started with Colima, it’s as simple as:
# Install Colima and the Docker client
brew install colima docker
# Start the VM (this only needs to be done once)
colima start
# Now you can use Docker commands as usual!
docker run hello-world
The ‘Nuclear’ Option: Demystifying Apple’s “Containers”
This is where the real confusion from the Reddit thread comes in. At WWDC, Apple announced “containers” for macOS. So, can we finally run Docker without a VM? No. Absolutely not.
When Apple says “container,” they mean something completely different. It’s a sandboxing technology for running macOS processes in an isolated way, but they share the host macOS kernel. This is a crucial distinction.
Think of it as a super-secure sandbox. It’s designed for running a piece of a macOS application or a background service (like a web server written in Swift) with a read-only filesystem and strict permissions. You can’t use it to run a Docker image of Ubuntu, because that image expects to be talking to a Linux kernel, not the macOS Darwin kernel.
Here’s a simple table to clear it up:
| Feature | Docker Containers (on Linux/in a VM) | Apple “Containers” (on macOS) |
|---|---|---|
| Host Kernel | Shares the Linux kernel (of the VM) | Shares the host macOS kernel |
| Guest OS | Bundles a full Linux userland (e.g., Alpine, Ubuntu) | Does not bundle a guest OS; uses host macOS libraries |
| Primary Use Case | Packaging and running cross-platform server applications (nginx, Postgres, Redis, your Go app) | Securely sandboxing a single macOS process or service |
| Image Format | OCI/Docker Image Format (e.g., from Docker Hub) | Not based on portable images; configured programmatically |
Warning: Do not try to solve your “I need to run Postgres for my web app” problem with Apple’s container API. It’s the wrong tool for the job. You’ll end up in a world of pain. Stick to Docker (via Docker Desktop, OrbStack, or Colima) for your development dependencies.
Wrapping It Up
So, to answer Sarah’s question: your Docker container on your Mac is slow because it’s running inside a Linux VM, and every file you touch has to cross that virtual boundary. By understanding this layered “sandwich” of macOS → VM → Linux → Docker, you can start to debug performance issues intelligently. And the next time you hear someone from Apple talk about “containers,” you’ll know they’re talking about a different beast entirely—a powerful tool for macOS app developers, but not a replacement for the Docker ecosystem we rely on every single day.
🤖 Frequently Asked Questions
❓ Why is Docker slow on my Mac, and how does it actually work?
Docker on macOS is slow because it runs inside a hidden Linux Virtual Machine (VM) due to kernel incompatibility. The Docker CLI on macOS connects to a Docker Daemon within this VM, and file operations must cross a virtual boundary, causing performance overhead, especially with many small files.
❓ How do Docker Desktop, OrbStack, Colima, and Apple’s native containers compare for running Docker images on macOS?
Docker Desktop uses a Linux VM with its own management, often incurring file I/O overhead. OrbStack and Colima also use Linux VMs but leverage Apple’s Virtualization.framework for superior efficiency and performance. Apple’s native ‘containers’ are a macOS sandboxing technology for isolating native macOS processes and are not designed to run Linux Docker images.
❓ What is a common mistake developers make when trying to run Linux-based applications on macOS using container technologies?
A common pitfall is mistakenly believing Apple’s native ‘containers’ can run standard Linux Docker images. Apple’s containers are for securely sandboxing macOS processes and share the host macOS kernel, making them incompatible with Docker images that expect a Linux kernel environment.
Leave a Reply