Stateless by design
No metadata, cache, or support directory. Apple container is the single source of truth, so a direct change shows up on the next command. No VM, no background processes.
Stateless · macOS · MIT
A small, stateless docker shim for Apple's container CLI on macOS. No Docker Desktop, no Podman, no sidecar.
Why
Docker Desktop, Podman, and third-party adapters each add a runtime, a VM, and a support directory. If your target is Apple's container, those layers are pure overhead.
No metadata, cache, or support directory. Apple container is the single source of truth, so a direct change shows up on the next command. No VM, no background processes.
Each command maps to a clean Apple container equivalent. Nothing rewritten, nothing mirrored, no daemon started. The shim is Python standard library only.
docker compose runs multi-service, statelessly. Pull, exec, start, stop, restart, and rm join the existing verbs; runtime membership lives as labels in Apple's own object store.
Commands
Three tiers. Anything outside them fails with an explicit exit-64 error instead of pretending to work, so scripts either succeed cleanly or stop loudly.
Core lifecycle and presentation, translated faithfully.
docker run -d …docker build -f -tdocker exec -d -i -u -edocker versiondocker info --formatdocker create …docker ps --filter --formatdocker inspect -f/--formatdocker portdocker start -a -idocker stop -s SIG -t Ndocker rm -fdocker image inspectdocker images / image lsConvenience verbs adapted to Apple's flags.
docker logs -f --tail Ndocker cpdocker system df / prunedocker stats --no-streamdocker restart -t Ndocker export -odocker login --password-stdindocker logoutdocker system infodocker container pruneImage, network, and volume verbs forwarded as-is.
docker pull / push / tagdocker save / loaddocker image prunedocker rmidocker network …docker volume …docker kill -s SIGNo verified Apple equivalent, so it fails loudly.
docker system eventsdocker commit / diffdocker run --add-hostdocker rename / historydocker run --network=noneHow it works
The shim sits between any caller that expects a docker binary and Apple's container CLI. It reads the arguments, maps them to the matching Apple subcommand, and forwards the call.
caller
compose · scripts · IDEs
stateless
no cache · no registry
Apple CLI
source of truth
Every Docker-shaped record (project membership, labels, network ownership) already lives in Apple's object store. The shim neither mirrors nor shadows it.
Install
Requires macOS 26 with Apple container 1.2.0 or newer, with the apiserver running. Apple's underlying Containerization package is already bundled. Every method gives you a docker command.
Homebrew or uv, whichever you have. Either one puts docker on your PATH.
$ brew install appautomaton/tap/docker-for-apple-container
# or with uv
$ uv tool install docker-for-apple-container
The apiserver must be running. Verify with status.
$ container system start
Run any supported command. The shim translates it and fails loudly on the rest.
$ docker compose up -d
Clone the repo and symlink the launcher onto your PATH:
$ git clone https://github.com/appautomaton/docker-for-apple-container.git
$ ln -sf "$(pwd)/docker-for-apple-container/bin/docker" ~/.local/bin/docker
No. It is a stateless translator, not a Docker replacement. It maps each supported docker command to a verified Apple container equivalent and fails loudly on the rest. Apple container is the single source of truth, so the shim persists nothing of its own.
Three tiers. Fully translated: version, info, build, run, create, exec, stop, rm, ps, inspect, port, images, image inspect, start. Container and image inspection share a bounded -f/--format field and JSON subset rather than a full Go-template engine. Container lists and port lookups are derived live from Apple's runtime metadata. Translated extras: logs, stats, cp, restart, export, login, logout, system info, system df, system prune, container prune. Thin passthrough: pull, push, tag, save, load, rmi, remaining image operations, network, volume, kill. Compose up, down, ps, logs, build, pull, exec, start, stop, restart, rm, config, and ls are statelessly orchestrated. Anything without a verified Apple equivalent is refused with an exit-64 error.
Project membership is stored as labels in Apple's own object store, exactly as Docker Compose stores it on containers, networks, and volumes. The shim queries Apple and filters on those labels for runtime verbs. start uses dependency order when a compose file is available; stop and rm reverse it; without a file they use stable service-name order. up, pull, build, and config require the file. DNS settings pass through to Apple, and service discovery selects addresses on networks shared by each pair of services.
No. The shim persists no Docker-shaped metadata, cache files, or support directory. There is no sidecar, no registry, and no database owned by the shim. The only trace is the docker command on your PATH.
Flags without a verified Apple equivalent fail loudly with an exit-64 error instead of pretending to work. A few run flags (--security-opt, --pids-limit, --storage-opt) are accepted as silent no-ops because Apple container documents no equivalent, and the shim surfaces this in its caveats.
macOS 26 with Apple container 1.2.0 or newer, with the container apiserver running (start it with container system start). Apple's Containerization Swift package is bundled as part of container and is not installed separately. The shim itself has no third-party runtime dependencies.