Docker-in-Docker
Run containers inside a box — storage drivers, caching, and cloud parity
Every AgentBox box ships its own dockerd, so an agent can docker build, docker run, and bring up Compose stacks without ever seeing your host's Docker daemon. The inner daemon lives in the box's own mount + network namespaces, so anything it spawns is contained — the same isolation guarantee described in core-concepts.
Running Docker inside a box
Docker-in-Docker is on by default — no flag needed. The box images bake docker.io + iptables, and an in-box dockerd is launched automatically (agentbox-dockerd-start). It is relaunched on agentbox start, since dockerd dies with the container.
dockerd is brought up and awaited ready before the supervisor starts your services, on both create and restart. That ordering means a docker run / docker compose declared as a service in agentbox.yaml is safe — it never races a not-yet-ready /var/run/docker.sock. (examples/express-ready ships a postgres service that relies on exactly this.)
The in-container vscode user is in the docker group, so the agent runs docker with no sudo.
agentbox shell mybox -- docker run --rm hello-world
agentbox shell mybox -- bash -lc 'cd /workspace && docker compose up -d'The inner daemon never touches your host Docker daemon. Use agentbox shell to drive it, let an agent use it directly, or prefer the supervisor for long-lived processes — see services-and-tasks for Compose vs the supervisor.
WHY
AgentBox never runs the outer container with --privileged. It grants only the capabilities DinD needs, which is exactly why the same setup works on cloud providers that reject privileged containers.
Storage driver
The storage driver is chosen automatically at runtime, not pinned in the image: the box prefers kernel-native overlay2 and falls back to fuse-overlayfs only when the kernel can't support it. You don't configure anything.
agentbox shell mybox -- docker info --format '{{.Driver}}'That prints overlay2 on most hosts, but the result is host-dependent.
HEADS UP
Don't try to force fuse-overlayfs — it's broken on recent kernels (notably Docker Desktop's 6.x linuxkit kernel), where inner docker run fails at execve(). AgentBox auto-selects overlay2 whenever the kernel supports it for exactly this reason. The host engine matters here — see local-docker.
Shared build cache
By default the data root /var/lib/docker is a per-box named volume, agentbox-docker-<id>, wiped on agentbox destroy — a clean slate per box.
HEADS UP
This volume is not captured by checkpoints. A checkpoint is a docker commit of the writable layer (/workspace + system); the inner dockerd's storage lives outside it. So a database or cache you run as a container starts empty on every new box created from a checkpoint — even though /workspace and any marker files were restored. It does survive stop/start (same volume), but not a fresh box. Gate migrate/seed tasks on the actual data (query the DB for a sentinel row), not on a filesystem marker — see services & tasks. To persist the data itself, run the DB as a native process with its data dir on the box filesystem, or bind a /workspace path in as the container's data volume.
To make pulled image layers and build cache persist across boxes, opt into the shared cache. This swaps to the shared agentbox-docker-cache volume, which is preserved on destroy and allowlisted in prune --all.
agentbox create --shared-docker-cache # uses agentbox-docker-cache volume
# or set it as the default for every box
agentbox config set box.dockerCacheShared true --globalbox.dockerCacheShared works in any config layer — see configuration for precedence and CLI commands for all flags.
HEADS UP
The shared cache is mutually exclusive at runtime: only one box can mount agentbox-docker-cache at a time. It's great for serial workflows but will conflict if you run boxes in parallel.
Cloud parity & limits
Daytona and Hetzner get the same DinD setup as the default docker provider — dockerd is auto-launched with no opt-in, and the data root lives on the sandbox/VPS filesystem (wiped with the box on destroy). Vercel cannot run nested containers at all.
| Provider | DinD |
|---|---|
| docker (default) | Yes — per-box volume; --shared-docker-cache available |
| daytona | Yes — auto-launched; no shared-cache option |
| hetzner | Yes — runs inside the VPS, baked into the prepare snapshot |
| vercel | No — CAP_SYS_ADMIN + seccomp block nested containers |
agentbox shell <cloud-box> -- docker infoNOTE
--shared-docker-cache is a docker-provider feature only. The Vercel provider sets launchDockerd: false, so if your workflow needs docker inside the box, choose docker, daytona, or hetzner.