How it works
What Kuvo Box runs on your Mac, and how the docker command reaches the engine inside the VM.
Docker containers need a Linux kernel, and macOS doesn’t have one. Like every Docker app for the Mac, Kuvo Box runs Linux in a virtual machine. What’s different is how little sits around it.
The pieces
There are two processes on your Mac: Kuvo Box itself, and the virtual machine, which macOS runs in a separate process for it.
The virtual machine
Kuvo Box uses Apple’s Virtualization framework, the same one behind most modern Mac VM apps. There’s no QEMU and no bundled hypervisor.
- Linux. Kuvo Box boots the official Alpine Linux kernel and installs Alpine onto a disk image on first launch. Alpine is small and boots quickly.
- Docker. The engine is the
dockerpackage from Alpine’s repository: the realdockerd,containerdandrunc, not a reimplementation. - Size. The VM gets half your CPU cores (at least two) and half your memory, up to 8 GB. The VM only takes memory from your Mac as it uses it.
- Disk. A sparse 64 GB disk image holds Alpine, Docker, and all your images, containers and volumes. It only takes the space that’s in use. Deleting files inside a VM doesn’t shrink its disk on the Mac by itself, so whenever Docker deletes something, and every time the VM starts, Kuvo Box has Linux tell macOS which blocks are free (a TRIM), and macOS frees them.
- Rosetta. If Rosetta is installed, Kuvo Box shares it with the VM and registers it for x86-64 binaries, so
linux/amd64images run without CPU emulation.
The boot scripts that run inside the VM are plain shell, kept short so they’re easy to read and audit. They live in GuestScripts.swift.
Reaching the engine
dockerd listens on its usual Unix socket inside the VM. A small relay (socat) exposes it on a vsock port, a direct channel between the VM and the Mac that doesn’t go over the network. Kuvo Box connects that channel to ~/.kuvo/docker.sock on your Mac.
The docker command, the kuvo command and the app itself all talk to that one socket, using Docker’s standard Engine API.
Ports
The VM has its own private network address behind NAT. When a container publishes a port, Kuvo Box sees it in the container list and opens the same port on 127.0.0.1, relaying each connection to the VM. When the container stops, the port closes again.
DNS
The VM, and the containers in it, look up names through your Mac, so they see the same DNS your Mac does. Some VPNs, firewalls and content filters block those lookups from the VM. When your Mac doesn’t answer but a public DNS server does, Kuvo Box adds Cloudflare (1.1.1.1) and Google (8.8.8.8) to the VM’s DNS servers, next to your Mac’s. It checks again on every start, and never does this while your Mac’s DNS answers.
Files
Two folders are shared into the VM with virtiofs:
/Users, mounted at the same path, so bind mounts like-v $PWD:/appwork without translating paths.- Kuvo Box’s own folder, used to hand the VM its boot scripts and kernel modules, and for the VM to hand back its network address and Docker’s log.
Starting and stopping
When you open Kuvo Box, it boots the VM and waits until Docker answers on the socket. That usually takes about three seconds.
When you quit, Kuvo Box asks the VM to shut down cleanly: Docker stops its containers, the disk is synced, and the VM powers off. If it hasn’t finished within 15 seconds, Kuvo Box stops it.
The app
Kuvo Box is written in Swift with SwiftUI and AppKit. There’s no web view. It speaks HTTP to the Docker socket directly with Apple’s Network framework, and draws live graphs and animations with Core Animation, so they keep running without redrawing the rest of the window.
The program, including the kuvo command, is a single 2.5 MB binary. It has three dependencies: swift-argument-parser for the CLI, SwiftTerm for the terminal, and Sparkle for updates.
Updates
Kuvo Box uses Sparkle, the standard update framework for Mac apps outside the App Store. Each release on GitHub includes a small feed, appcast.xml, that names the new version and carries an EdDSA signature of its download. Kuvo Box checks the newest release’s feed once a day, and only installs an update whose signature matches the public key built into the app. Updates are also signed with a Developer ID and notarized by Apple, like the first download.
Sparkle is trimmed to what Kuvo Box needs: Apple silicon only, English only, and without the helper services that only sandboxed apps use. That brings it to under 1 MB.
Not Apple’s containerization
macOS 26 includes Apple’s own container framework, which runs each container in its own lightweight VM. Kuvo Box doesn’t use it. Kuvo Box runs one VM with the full Docker Engine, so Compose, networks, volumes, BuildKit and the rest of the Docker API work exactly as they do on Linux.