Stateless · macOS · MIT

Docker commands,
routed to Apple container.

A small, stateless docker shim for Apple's container CLI on macOS. No Docker Desktop, no Podman, no sidecar.

Python stdlib only MIT licensed View source on GitHub

Why

A translator, not another runtime.

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.

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.

Pure translation

Each command maps to a clean Apple container equivalent. Nothing rewritten, nothing mirrored, no daemon started. The shim is Python standard library only.

Compose, too

docker compose runs multi-service, statelessly. Project membership lives as labels in Apple's own object store, exactly as Docker Compose stores it.

Commands

What it supports.

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.

Fully translated

Core lifecycle and inspection, mapped 1:1.

  • docker run -d …
  • docker build -f -t
  • docker exec -i -e
9 more
  • docker version
  • docker info --format
  • docker create …
  • docker ps --filter --format
  • docker inspect --format
  • docker start
  • docker stop -t N
  • docker rm -f
  • docker image inspect

Translated extras

Convenience verbs adapted to Apple's flags.

  • docker logs -f --tail N
  • docker cp
  • docker system prune
6 more
  • docker stats --no-stream
  • docker restart -t N
  • docker export -o
  • docker login --password-stdin
  • docker logout
  • docker system info

Thin passthrough

Image, network, and volume verbs forwarded as-is.

  • docker images
  • docker pull / push / tag
  • docker save / load
5 more
  • docker rmi
  • docker image …
  • docker network …
  • docker volume …
  • docker kill -s SIG

Refused by design

No verified Apple equivalent, so it fails loudly.

  • docker system events
  • docker commit / diff
  • docker run --add-host
3 more
  • docker rename / history
  • docker run --network=none
  • Anything unknown (exit 64)

How it works

One hop, no state.

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.

docker

caller
compose · scripts · IDEs

shim

stateless
no cache · no registry

container

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

Running in two minutes.

Requires macOS with Apple container 1.0.0, with the apiserver running. There is no Python to install and no dependencies. Every method gives you a docker command.

Install

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

Start Apple container

The apiserver must be running. Verify with status.

$ container system start

Use docker as usual

Run any supported command. The shim translates it and fails loudly on the rest.

$ docker compose up -d
Install from source instead

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

FAQ

Questions, answered.

If something is missing, the README is the source of truth.

Does it replace Docker Desktop?

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.

What Docker commands does it support?

Three tiers. Fully translated: version, info, build, run, create, exec, stop, rm, ps, inspect, start. Translated extras: logs, stats, cp, restart, export, login, logout, system prune. Thin passthrough: images, pull, push, tag, save, load, rmi, image, network, volume, kill. Compose verbs are statelessly orchestrated. Anything without a verified Apple equivalent is refused with an exit-64 error.

How does docker compose work without state?

Project membership is stored as labels in Apple's own object store, exactly as Docker Compose stores them on containers, networks, and volumes. The shim queries Apple and filters on those labels for down, ps, logs, and ls. Only up, build, and config read the compose file.

Does it install any sidecar or daemon?

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.

What happens to unsupported flags?

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.

What are the requirements?

macOS with Apple container 1.0.0, with the container apiserver running (start it with container system start). There is nothing else to install: the shim is pure Python standard library and runs on the Python that ships with macOS, so there are no dependencies to manage.