docs/recipes/docker/docker-in-sandbox.mdx
This recipe starts a complete Docker environment inside a microsandbox VM. It is useful for sandboxed builds, agent workflows that need their own Docker daemon, or experiments you do not want leaking onto the dev machine. The host's Docker setup, if any, is left untouched.
The command below boots the docker:dind image, starts Docker inside the sandbox, waits for it to be ready, and then opens an interactive shell. From there, Docker commands run against the daemon inside the sandbox, not your host.
msb run --name docker-demo --replace \
--memory 2G \
--mount-named docker-data:/var/lib/docker \
--script start='dockerd >/tmp/dockerd.log 2>&1 &
timeout 60 sh -c "until docker info>/dev/null 2>&1;do sleep 1;done" || {
cat /tmp/dockerd.log
false
}
exec sh' \
--entrypoint start \
docker:dind
This command does three things:
docker:dind image in a sandbox named docker-demo.docker-data at /var/lib/docker, where Docker stores images, containers, and build cache.start script as the entrypoint. The script starts Docker, waits until it is ready, and then opens a shell.--mount-named docker-data:/var/lib/docker is idempotent. If docker-data does not exist, the CLI creates it before starting the sandbox. If it already exists with compatible settings, the same command reuses it, so pulled images and created containers can survive msb rm docker-demo.
From the sandbox shell, run a nested Ubuntu container:
docker run -it --rm ubuntu bash
You are now in a container running inside Docker, which is itself running inside the microsandbox VM. Exit the Ubuntu container with exit to return to the docker-demo sandbox shell.
You can also verify the daemon with a short non-interactive command:
docker run --rm hello-world
exit
msb rm -f docker-demo
msb volume rm docker-data
Remove docker-data only when you no longer need the images, containers, and build cache stored by the nested daemon.
Use the default security profile for this recipe. Docker-in-Docker needs normal guest-root mount privileges, so restricted sandboxes are not supported here.
The named mount gives Docker its own storage at /var/lib/docker. That matters because the sandbox root filesystem is already overlay-backed, and Docker's default storage driver also uses overlay layers. Keeping Docker's data directory on a named mount avoids putting Docker's overlay storage directly on top of the sandbox root overlay.
If you want to avoid the named volume, you can ask Docker to use the vfs storage driver instead:
msb run --name docker-demo --replace \
--memory 2G \
--script start='dockerd --storage-driver=vfs >/tmp/dockerd.log 2>&1 &
timeout 60 sh -c "until docker info>/dev/null 2>&1;do sleep 1;done" || {
cat /tmp/dockerd.log
false
}
exec sh' \
--entrypoint start \
docker:dind
The tradeoff is performance and disk usage. vfs copies full filesystem trees instead of using overlay layers, so pulls and builds can be slower and use more space. Prefer the named-mount version for normal Docker-in-Docker work.
--memory 2G. Increase it for larger builds or memory-hungry containers.