Registers QEMU user-mode emulators with the kernel's binfmt_misc via Docker (tonistiigi/binfmt) so the sandbox can run and build container images for other CPU architectures. Requires a Docker-in-Docker base template.
registry-1.docker.io:443
auth.docker.io:443
production.cloudflare.docker.com:443
index.docker.io:443
archive.ubuntu.com:80
security.ubuntu.com:80
ports.ubuntu.com:80
download.docker.com:443
sbx run <agent> --kit docker.io/sbx/qemu-kit:latestRun the following command to install sbx on your machine.
brew install docker/tap/sbxwinget install Docker.sbxA mixin kit that registers QEMU user-mode emulators with the kernel's binfmt_misc using Docker (tonistiigi/binfmt) — the same mechanism docker buildx uses for cross-platform builds. Once composed onto a Docker-in-Docker agent, the sandbox can run and build container images for non-native CPU architectures (for example linux/arm64 on an amd64 host, and vice versa).
sbx run claude --kit "docker.io/sbx/qemu-kit:latest" .
Or straight from this repository over git:
sbx run --kit "git+https://github.com/docker/sbx-kits-contrib.git#dir=qemu" claude
Or with a local clone of this repo:
sbx run claude --kit ./qemu/ .
Prerequisites:
docker at startup, so compose it onto a *-docker sandbox template (for example docker/sandbox-templates:shell-docker). The startup hook fails loudly with a clear message if docker isn't on PATH.Inside the sandbox:
docker run --rm --platform linux/arm64 alpine uname -m # -> aarch64
docker buildx build --platform linux/amd64,linux/arm64 -t demo .
ls /proc/sys/fs/binfmt_misc/qemu-* # registered emulators
tonistiigi/binfmt --install talks to the in-sandbox Docker daemon (DinD), which is only up once the container is running — it is not available during install hooks, which run before the entrypoint. So the actual registration is a startup hook. startup always runs after install, which is why the mount prerequisite (below) can be handled at install time and is guaranteed to be present when the startup hook runs.
mount is installed, then used to mount binfmt_miscEmulator registrations live in the binfmt_misc pseudo-filesystem, which must be mounted at /proc/sys/fs/binfmt_misc before handlers can be registered or inspected. That needs the mount tool, so the install hook ensures it's present (apt-get install mount only if the base image lacks it). The startup hook then mounts the filesystem, guarding on the register control file — which exists only once binfmt_misc is mounted — so a re-mount is skipped when it's already there.
startup hooks run on every container start (create, stop/start, daemon restart, host reboot), so the body is idempotent. binfmt_misc registrations are kernel-global and survive sandbox restarts, so before pulling and running tonistiigi/binfmt the hook checks for existing qemu-* handlers and skips the network-heavy install when they're already registered. When it does need to install, it waits (up to 60s) for the Docker daemon to accept connections first.
permissions.network.allow is the kit's complete outbound contract — CI runs e2e under a deny-all policy.
| Domain | Why |
|---|---|
registry-1.docker.io | Docker Hub registry — serves the tonistiigi/binfmt manifest |
auth.docker.io | Docker Hub token endpoint for the pull |
production.cloudflare.docker.com | Docker Hub layer-blob CDN |
index.docker.io | Legacy Docker Hub index some client flows still touch |
archive.ubuntu.com | Ubuntu apt archive, amd64 — apt-get install mount |
security.ubuntu.com | Ubuntu security pocket, amd64 — refreshed by the same apt-get update |
ports.ubuntu.com | Ubuntu archive/security for arm64 (Apple Silicon sandboxes) |
download.docker.com | Docker's apt repo, pre-added by the *-docker templates — apt-get update refreshes every configured source and fails if any is blocked |
The apt-installed mount package and the binfmt_misc mount are sandbox-local and disappear with the sandbox (sbx rm <name>). The emulator registrations are not — binfmt_misc is global to the Docker VM's kernel, so they persist for other sandboxes and for the host's Docker until the VM restarts. To remove them explicitly without restarting the VM:
docker run --privileged --rm tonistiigi/binfmt --uninstall 'qemu-*'