The Docker you wish Docker shipped.

Morbstack runs unmodified upstream Moby — dockerd and containerd, stock, no engine patch — inside one shared, lightweight Linux VM on Apple's Virtualization.framework — free forever, Apache-2.0, no account, no telemetry.

The Morbstack containers list in light mode, showing running and stopped containers with status, image, and port columns. The Morbstack containers list in dark mode, showing running and stopped containers with status, image, and port columns.
Why Morbstack

Six claims, each one checkable.

No embellishment — every line below is true today and traceable to this repository's own license file, source tree, or docs.

Free forever

No tier, no seat limit, no company-size threshold. Every feature that runs on your machine costs nothing, for anyone.

Apache-2.0

The whole project — daemon, CLI, app, guest init — is Apache-2.0. See LICENSE and NOTICE in the repository.

No account

Nothing to sign in to. Nothing phones home to check a license. There is no account system anywhere in this codebase.

No telemetry, no license nags

No analytics, no crash reporting service, no "upgrade to Pro" interstitials. What you run is what's in the repo.

Unmodified upstream Docker Engine

A static upstream Docker Engine build runs inside the guest, not a reimplementation — dockerd and containerd are both stock, archive-hash-pinned binaries with no downstream patch. Published ports (including docker run -P) are held on the Mac by a small Morbstack userland proxy, invoked through dockerd's own stock --userland-proxy-path hook.

Native SwiftUI, zero web views

No Electron, no Chromium, no embedded browser anywhere in the app. SwiftUI and Foundation, the same frameworks a Mac-native app is supposed to use.

Performance

Measured numbers, and separately, targets.

Every number below is labelled with the file it came from. The two groups are not the same kind of claim — conflating them is exactly the kind of dishonesty this project exists to avoid.

Measured

Real, timed runs against a live build — not simulated, not estimated. See docs/roadmap.md and docs/parity.md.

2.09 s
Cold boot to docker run hello-world completing — socket-activated, no pre-warmed VM state.
docs/roadmap.md — M0
2.16 s
Cold VM boot to a usable Docker Engine API.
docs/parity.md — check #1
29.7.1
Docker Engine version in the guest, driven by a stock Docker CLI 27.4.0 over the relay — no patched client required.
docs/parity.md — check #1
0.44 s
A cached multi-stage Dockerfile rebuild, classic builder.
docs/parity.md — check #12
10.7 s / instant
morb stop takes 10.7s; morb start brings a --restart unless-stopped container back running, no manual restart.
docs/parity.md — check #24
~5.1x / ~3.8x / ~2.3x
amd64-via-Rosetta slowdown vs. native arm64: SHA-256, RSA-2048 sign, RSA-2048 verify.
docs/parity.md — check #16
Target — not yet measured

These are commitments, not results. docs/roadmap.md commits Morbstack to publishing accurate, current status against every one of these via morb bench from milestone M2 onward.

Public performance target table
TargetGoal
Cold boot≤ 2.0 s
Resume (from suspend-to-zero)≤ 500 ms
Idle host CPU≤ 0.1 %
Idle wakeups< 20 / s
Host RSS (morbstackd, idle)≤ 120 MB
Guest memory floor≤ 256 MB
git status on a bind-mounted Linux tree, vs. native≤ 2x native
npm install on a bind-mounted project, vs. native≤ 1.5x native

Source: docs/roadmap.md, "Public performance target table".

Status

Pre-release. Here's exactly where it stands.

Pre-release M0 complete Kubernetes landed

Morbstack has passed M0 — the core bet (unmodified upstream Docker Engine, one shared VM, fast boot) plus published ports, container outbound networking, disk persistence across a restart, and docker compose up -d. It now has a native macOS operations app, reviewed CLI setup, bundled Compose and Buildx, and a local Kubernetes cluster (morb k8s). These are implemented, not release-certified: clean-profile and real-engine acceptance remain required. *.morb.local DNS and the gaps below are still real.

20 PASS 3 PARTIAL 6 FAIL — out of 29 real drop-in-compatibility checks, run against a live build
What doesn't work yet
  • No *.morb.local domains or local HTTPS. Those need a narrowly-scoped DNS and trust design; neither is claimed today.
  • Hot-reload still lacks an inotify bridge. A host-side edit is correct the instant you read it, but watchers need polling until the explicitly-scoped FSEvents bridge has a guest injection endpoint.
  • Published-port parity is intentionally narrow. Fixed loopback TCP has synchronous admission; dynamic/range ports, VM-stop persistence, and any not-yet-implemented protocol remain unavailable rather than silently misrepresented.
  • Migration is images-only. The native review/transfer/verification workflow deliberately excludes volumes, bind mounts, containers, credentials, and registry access until each can be proven safely.
What already works
  • Core CLI surface — ps/images/pull/run/exec/logs/inspect/cp/stats/events — byte-for-byte the shape real Docker produces.
  • Multi-service Compose stacks with healthchecks, named volumes, and custom networks.
  • Bundled Docker, Compose, and Buildx through an explicit, reversible setup transaction; direct socket discovery is created only when it is safe.
  • Published ports, outbound container networking, and disk persistence across morb stop / morb start.
  • amd64 images via Rosetta, verified bit-identical against native output.
  • A native operations app with actual container, stack, image, volume, network, BuildKit, Kubernetes, disk, and migration routes.

Read the full 29-check parity audit →