docs/recipes/docker-in-sandbox.mdx
This recipe gives you a complete, throwaway Docker environment inside a microsandbox VM. It is useful for sandboxed builds, isolating agent workflows that need their own Docker, or any experiment you don't want leaking onto the dev machine. The host's Docker setup (if any) is left untouched.
docker:dind is a regular OCI image, so microsandbox can boot one inside a microVM. You boot the image into a shell, start dockerd, and from there every Docker command in that shell talks to the nested daemon rather than the host's.
Storage needs one small workaround. The sandbox root is already an overlayfs mount, and Docker's default storage driver also wants overlayfs for container layers. Stacking the two produces overlay-on-overlay mount errors. The fix is to point Docker's data root at /tmp, which microsandbox already mounts as tmpfs.
Save this as start-docker in the directory you'll run msb from:
#!/bin/sh
set -eu
if docker info >/dev/null 2>&1; then
echo "Docker is already running."
exit 0
fi
dockerd --data-root=/tmp/docker >/tmp/dockerd.log 2>&1 &
printf "Starting Docker"
i=0
while ! docker info >/dev/null 2>&1; do
i=$((i + 1))
if [ "$i" -ge 60 ]; then
echo
cat /tmp/dockerd.log
exit 1
fi
printf "."
sleep 1
done
echo " ready"
Make it executable:
chmod +x start-docker
msb run --name docker-demo --replace \
--memory 2G \
--tmpfs /tmp:1G \
--entrypoint sh \
--script-path start-docker:./start-docker \
docker:dind
--entrypoint sh replaces the image's default DinD entrypoint with an interactive shell. --script-path makes start-docker available inside the sandbox at /.msb/scripts/start-docker, which is already on PATH.
From the sandbox shell, run the helper:
start-docker
Once it prints ready, the daemon is running and the Docker client in the same shell is connected to it.
Verify the daemon with hello-world:
docker run --rm hello-world
For something closer to a real workload, start a long-running container and tail its logs:
docker run -d --name heartbeat alpine sh -c 'while true; do date; sleep 1; done'
docker ps
docker logs -f heartbeat
Ctrl-C stops the tail; heartbeat continues running in the background.
For a visual demo, run cmatrix in a nested Alpine container:
docker run --rm -it alpine sh -lc 'apk add --no-cache cmatrix >/dev/null && cmatrix -ab'
q exits.
exit
msb rm -f docker-demo
/tmp is 1 GiB here. Increase --tmpfs /tmp:N if you plan to pull larger images.upperdir / workdir.msb volume, Docker's data root can sit on a real block device and survive sandbox removal.