Use Docker Sandboxes as Your Development Environment
Set up your development tools in Docker Sandboxes, control network access, and reuse your environment with snapshots and Dockerfile-based templates.
In early November 2026, I started writing a book on Docker Sandboxes. Using my existing setup, I wrote in Markdown and built a PDF with Pandoc and XeLaTeX. Then, I got a new laptop: MSI Stealth 16 Mercedes-AMG (because I'm a fan of the car brand). And, when I asked my AI agent to compile the book, it installed TeX Live under /tmp. Well, not a terrible idea, as I like keeping the globally installed packages to a minimum.
But, after a restart, I would have needed a new TeX installation to build the PDF. So I decided to set up a Docker Sandbox with the TeX toolchain to compile the book!
The same idea works for a Node.js app, a Python project, or any other development toolchain: install your tools inside a sandbox and keep the host setup small. My book build is just the example we'll use here.
Docker Sandboxes uses microVMs to isolate local workloads from the host, with the sbx CLI managing the environment. We'll create a shell sandbox, install our tools, save a snapshot, and then define the setup in a Dockerfile so we can rebuild and share it.
Version note: Tested with Docker Sandboxes v0.51.0 on November 9, 2026: dependency installation, snapshot reuse, and Dockerfile build/export/import, with a Node.js → Pandoc → XeLaTeX PDF smoke test in each environment. The actual
npm run book:sbx:pdfcommand was also verified on the rebasedcodex/docker-sandboxes-in-actionbranch, producing a 42-page PDF in both environments. Check your CLI version withsbx --version.
Install Docker Sandboxes
For local sandboxes, the installation prerequisites are:
- Linux: Ubuntu 24.04 or later, with KVM virtualization available and your account in the
kvmgroup. - macOS: macOS 14 or later on Apple silicon.
- Windows: Windows 11 on a 64-bit Intel or AMD processor, with Windows Hypervisor Platform enabled.
The sbx CLI does not require Docker Engine on the host. However, the Dockerfile section below uses docker build and docker image save, so you'll also need a working host Docker Engine or Docker Desktop installation for that part.
Since my new laptop runs Ubuntu, I installed Docker Sandboxes with:
curl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh
sudo apt install docker-sbx
So, piping a curl output into a shell is not a good idea. But, this is get.docker.com, and I trust Docker. Don't do it for everything you find on the internet.
On Mac, install Docker Sandboxes with Homebrew:
brew trust docker/tap
brew install docker/tap/sbx
And as Duke Nukem said: "I don't do Windows." But Docker Sandboxes does! Windows users can follow the official installation guide.
Also, don't forget to log in:
sbx login
Let's Do It: Start a Sandbox
Great! Before starting a sandbox, let's enforce a network policy to disallow all network access by default. This is a good practice to avoid accidental data leaks or unwanted connections, especially if I later run my AI agent inside the sandbox. So, let's do it:
sbx policy init deny-all
This will create a default deny-all policy for all sandboxes. You can always add exceptions later.
To check if it's working, run:
sbx policy ls
sbx policy check network github.com:443
Good! Now, let's create the sandbox:
sbx create --name sbx-book shell .
This command creates a new sandbox named sbx-book using the shell workload kit and mounts the current directory into it. In v0.51.0, this kit uses Debian 13; the host needs registry access to fetch it on first use. You can now enter the sandbox with:
sbx run --name sbx-book
Entering the sandbox, you can check a few things:
ls
git --version
The current directory is mounted read-write inside the sandbox because I used . as the last argument. Files created or changed here immediately appear on the host, including the PDF output.
The v0.51.0 shell kit includes Git, but Node.js and npm need to be installed for this example. My book uses Node.js to assemble the Markdown files into a single document before Pandoc and XeLaTeX build the PDF.
Install Dependencies in the Sandbox
Now it's time to install the dependencies for the book build. First, check the sandbox's operating system and configured package repositories:
cat /etc/os-release
find /etc/apt -maxdepth 2 -type f \( -name '*.list' -o -name '*.sources' \) \
-exec cat {} +
The host runs Ubuntu, but the current shell kit runs Debian. The network allowlist needs to match the repositories inside the sandbox.
Now try:
sudo apt update
With our deny-all policy, this should fail until the required hosts are allowed. Check sbx policy ls if it succeeds: active kit or existing rules may already permit access.
In the shell kit tested with v0.51.0, both the Debian package and security-update sources use deb.debian.org, and an additional Docker Hardened Images repository uses dhi.io. Allow those hosts from another terminal on the host:
sbx policy allow network --sandbox sbx-book \
'deb.debian.org,dhi.io'
Match the rule to the hosts you found above. Other images may use security.debian.org, Ubuntu mirrors, or additional repositories. A blocked repository can make apt update report both a 403 error and a misleading "repository is not signed" message; fix the network rule rather than disabling signature verification.
Now, let's install the dependencies, including Node.js and npm for my build script:
sudo apt update
sudo apt install -y --no-install-recommends \
nodejs npm pandoc latexmk texlive-xetex texlive-latex-extra \
texlive-fonts-recommended texlive-fonts-extra \
lmodern fonts-lmodern fonts-dejavu fontconfig
In this test, apt downloaded about 820 MB and added roughly 2.5 GB. It also replaced the kit's Python 3.14 packages with Debian Python 3.13 packages, so review the proposed package changes if your project depends on a particular Python version.
With the dependencies installed, I can run my project-specific build command inside the sandbox (use your own build or test command here):
npm run book:sbx:pdf
Create a Sandbox Template: The docker commit Way
Installed tools persist when we stop and restart this sandbox. Now we want to preserve the environment for reuse in other sandboxes. In the container world, we can create an image from an existing container using docker commit.
Docker Sandboxes has an equivalent: sbx template save.
First, exit and stop the sandbox from the host:
sbx stop sbx-book
Now, save its filesystem as a reusable template:
sbx template save sbx-book sbx-book:texlive-v1
That's it! We have created a sandbox template containing Pandoc, XeLaTeX, Node.js, and all the installed fonts.
Let's check:
sbx template ls
Now, create a new sandbox using this template:
sbx create \
--name sbx-book-snapshot \
--template sbx-book:texlive-v1 \
--pull never \
shell .
The --pull never option tells Docker Sandboxes to use the locally saved image rather than pulling it from a registry.
Enter the new sandbox:
sbx run --name sbx-book-snapshot
And check the toolchain:
pandoc --version
xelatex --version
node --version
fc-match "Latin Modern Roman"
kpsewhich yfrak.tfm
The last two commands check the Latin Modern and Fraktur fonts.
Finally:
npm run book:sbx:pdf
And there we go! A new sandbox with the same tools, without installing TeX Live again.
But, we have a problem.
Just like docker commit, this approach saves the current state without documenting how we created it. What if I want to update Pandoc, change the packages, or share the build instructions?
Well, Docker has a solution for that: Dockerfile.
And Docker Sandboxes can use it too!
Create a Sandbox Template: The Dockerfile Way
Instead of installing everything manually and taking a snapshot, let's define the environment in a Dockerfile.
Create a directory called sbx-template and add a Dockerfile:
FROM docker.io/sbx/shell-image:latest
USER root
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
nodejs \
npm \
pandoc \
latexmk \
texlive-xetex \
texlive-latex-extra \
texlive-fonts-recommended \
texlive-fonts-extra \
lmodern \
fonts-lmodern \
fonts-dejavu \
fontconfig && \
rm -rf /var/lib/apt/lists/*
USER agent
Looks familiar, doesn't it?
We're extending Docker's maintained shell image, installing our dependencies, and returning to the non-root agent user. The old docker/sandbox-templates:shell image is no longer refreshed. Note that the standalone sbx/shell-image:latest tested here uses Ubuntu 26.04, while the built-in shell kit above uses Debian 13. They provide different starting environments, so package versions and repository hosts can differ.
This is important: use an existing sandbox-compatible image as the base. A random Ubuntu image might not contain the users, tools, and configuration that Docker Sandboxes expects.
Now, from the host, let's build the image:
docker build \
-t sbx-book:texlive-v2 \
./sbx-template
Yes, that's just docker build!
We now have a version-controlled definition of our development environment, making it easier to rebuild, update, and share. The latest tag and unpinned packages can change between builds. For stricter reproducibility, pin the base image digest and package versions, using a package repository snapshot when needed.
But there's a small catch.
Docker Sandboxes doesn't share the host Docker Engine's image store. So, although we built the image successfully, sbx can't automatically use it.
We need to export and import it:
docker image save \
sbx-book:texlive-v2 \
-o sbx-book-texlive-v2.tar
sbx template load sbx-book-texlive-v2.tar
Now our image is available to Docker Sandboxes.
Let's create a new sandbox from it:
sbx create \
--name sbx-book-built \
--template sbx-book:texlive-v2 \
--pull never \
shell .
And enter it:
sbx run --name sbx-book-built
Now, let's compile the book again:
npm run book:sbx:pdf
This runs the same build command, but this time the environment is defined in source code.
Also, if we want to share the template through Docker Hub instead of transferring a tar file, we can tag and push it to a registry and then refer to that image when creating the sandbox.
What About Docker Sandbox Kits?
There's another way to configure a development environment: Docker Sandbox Kits.
A template supplies a reusable filesystem image. A kit also describes runtime requirements, such as network access, credential requests, and instructions for an AI agent. A workload kit supplies the base environment and launch command; mixin kits add tools or behavior to that workload.
With Kit v3, we can define the environment using a YAML descriptor and a companion Dockerfile. Docker Sandboxes can build a local kit automatically when we create a sandbox from its directory.
Once you have authored a workload kit in my-kit following the kit authoring guide, the workflow looks like this:
sbx run --name my-project ./my-kit
No manual docker image save or sbx template load required.
Kits are particularly useful when we're combining an AI agent with development tools and need to define which services it can reach.
For our book build, the custom Dockerfile is sufficient. But when I want to give an AI agent this environment along with specific permissions and instructions, Kits are worth exploring.
A Few Security Considerations
Before finishing, there are a few things worth mentioning:
- The workspace is writable. A process or AI agent can change or delete files in the directly mounted directory. MicroVM isolation does not protect those shared files. For Git projects, clone mode (
--clone) gives the sandbox a private working copy so you can review changes before bringing them back to the host. - Templates are not complete backups. The workspace mounted from the host is not included in a saved template.
- Network policies are separate. Saving a sandbox as a template does not copy its network permissions to a new sandbox.
- Don't bake secrets into images. Snapshotting a sandbox can capture credentials or other sensitive files.
- Use a non-root user. Our Dockerfile installs system packages as root but returns to the
agentuser. - Keep dependencies updated. Rebuilding the template lets us incorporate security updates into the development environment.
Also, texlive-fonts-extra is huge! Our image isn't exactly lightweight.
But at least I don't need to download the entire toolchain every time I create a new sandbox.
Docker vs. Docker Sandboxes: Command Cheat Sheet
Now that we've used both Docker and Docker Sandboxes, let's compare their equivalents.
| Docker Sandboxes | Docker | Purpose |
|---|---|---|
| Sandbox | Container | Isolated execution environment |
| Sandbox template | Docker image | Reusable filesystem and toolchain |
| Sandbox Kit | Image + runtime configuration | Declarative environment configuration |
sbx create | docker create | Create an environment |
sbx run | docker run / docker start -ai | Create or enter an environment |
sbx exec | docker exec | Execute commands |
sbx ls | docker ps -a | List environments |
sbx stop | docker stop | Stop an environment |
sbx rm | docker rm | Remove an environment |
sbx template save | docker commit | Save filesystem changes as an image |
| Dockerfile for a sandbox template | Dockerfile | Define an image declaratively |
docker build | docker build | Build a template image |
sbx template load | docker image load | Import an image into the runtime |
sbx template ls | docker image ls | List images |
sbx template rm | docker image rm | Remove images |
sbx policy allow network | No direct Docker CLI equivalent | Control outbound network access |
These are functional comparisons, not exact architectural equivalents. Docker Sandboxes provides stronger isolation using microVMs, and its policies add controls that regular Docker container commands don't provide directly.
Conclusion
And that's it! We now have a reusable, isolated development environment. Mine builds books with Pandoc, XeLaTeX, and Node.js; yours could run a Python project, a web app, or another toolchain.
We've done it two ways:
- Snapshot: Install dependencies manually, then use
sbx template save, similar todocker commit. - Dockerfile-based setup: Define the toolchain with a
Dockerfile, build it with Docker, and load the image into Docker Sandboxes.
No more installing TeX Live under /tmp. No more missing dependencies after a restart. And my host stays clean.
Not bad for a sandbox! 🐳
