Skip to content

About

Templates for docker sandbox

Resources

Stars

1 star

Watchers

1 watching

Forks

Repository files navigation

sandbox-templates

Reusable Docker Sandboxes (sbx) bases for shell, Claude Code and OpenCode, plus sbx-up, which recreates a project's sandbox from them with the project's own additions. Renovate keeps the base image, tool versions and the agent mixins up to date.

Pieces

  • shell-base/: v3 workload kit. Ubuntu docker/sandbox-templates:shell-docker with Docker, mise (node, hunk, helix), supply-chain presets for npm/pnpm/uv, the shared agent guidance (config/AGENTS.md), a default helix config (config/helix/) and a base network allow list. sbx builds it from this directory. Project-specific tools such as pnpm or uv go in the project's .sbx-kits/.
  • claude-mixin.ref: Docker's claude-mixin kit, pinned by digest. It adds Claude Code, API key / subscription sign-in through the sbx proxy (real credentials stay on the host), session volumes and Claude's allow list on top of shell-base.
  • opencode-mixin.ref: Docker's opencode-mixin kit, pinned by digest to latest (its version tags need a newer sbx, see renovate.json). It adds OpenCode, optional provider credentials through the sbx proxy and OpenCode's allow list on top of shell-base.
  • bin/sbx-up: composes shell-base and a mixin with a project's mixins and (re)creates the sandbox.
  • project-template/: a starting .sbx-kits/ for projects.

Setup

On the host (macOS), where sbx runs; sbx-up doesn't work inside a sandbox.

  1. Check that sbx works: sbx version and sbx ls.

  2. Clone this repo. sbx-up finds shell-base/ and the *-mixin.ref files through its own location, so the clone can live anywhere:

    git clone git@github.com:simbados/sandbox-templates.git ~/projects/sandbox-templates
  3. Put sbx-up on PATH, either as a symlink into a directory already on it:

    mkdir -p ~/.local/bin
    ln -s ~/projects/sandbox-templates/bin/sbx-up ~/.local/bin/sbx-up
    # only if ~/.local/bin isn't on PATH yet (zsh):
    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc

    or with the repo's bin/ on PATH: echo 'export PATH="$HOME/projects/sandbox-templates/bin:$PATH"' >> ~/.zshrc.

  4. Check: sbx-up -h prints the usage, and sbx-up -n shell in any directory prints the sbx commands it would run without running them.

  5. For Claude Code, optionally store an API key once: sbx secret set anthropic. Without one, use /login inside Claude Code; the sbx proxy keeps the real tokens on the host either way.

  6. In each project, copy the template mixin and commit it with the project:

    sbx-up kit            # copies project-template/.sbx-kits/ into the current directory

    Make sure .sbx-kits isn't matched by a global gitignore (git check-ignore -v .sbx-kits).

To update the bases later, git -C ~/projects/sandbox-templates pull, then sbx-up -r in a project rebuilds its sandbox from them (sbx reuses its build cache when nothing changed).

Usage

From a project directory, on the host:

sbx-up shell          # shell-base + the project's .sbx-kits/ mixins, opens fish
sbx-up claude         # ... + claude-mixin, starts Claude Code in auto mode
sbx-up opencode       # ... + opencode-mixin, starts OpenCode
sbx-up -r claude      # rebuild: remove the sandbox and create it from the current kits
sbx-up -n claude      # print the sbx commands instead of running them
sbx-up shell ~/projects/x -- -lc 'make test'   # other directory, own launch arguments
sbx-up sealed claude  # throwaway sandbox, see below
sbx-up sealed -c test claude  # another one next to it, named sealed-claude-test
sbx-up sealed -k claude  # sealed, but kept after the session; run again to reattach
sbx-up kit [PATH]     # copy project-template/.sbx-kits/ into a project

The sandbox is named <project>-<flavor>, e.g. <project>-shell or <project>-claude. If it already exists, sbx-up starts it again (sbx run --name, which also restarts a stopped one) and attaches to it; it only creates a sandbox when none exists. A sandbox keeps the kits it was created with, so after git pull here or an edit in .sbx-kits/, run sbx-up -r: that removes the sandbox and creates it from the current kits. Anything installed by hand in the old sandbox is gone then, and so is everything else sbx rm removes with it ("all associated resources"); put lasting setup in .sbx-kits/.

sbx-up sealed shell|claude|opencode starts a throwaway sandbox named sealed-<flavor>. It mounts an empty directory (~/.cache/sbx-up/sealed-<flavor>) instead of a project and adds no project mixins. It runs sbx run --rm (sbx 0.47.0 or later), so sbx removes the sandbox when the session ends. A sandbox left behind by an interrupted run is removed, and the directory emptied, at the next sealed start. Only one of each name can run at a time, since a new one replaces the old; -c NAME gives a sealed sandbox its own name and directory (sbx-up sealed -c test claude runs sealed-claude-test on ~/.cache/sbx-up/sealed-claude-test), so several can run side by side. -k keeps the sandbox and its directory when the session ends (no --rm); the next sbx-up sealed -k with the same flavor and -c name reattaches to it, and sbx-up -r sealed -k starts it fresh. A sealed start without -k still replaces it, so give kept ones a -c name if you also use plain sealed sandboxes of that flavor.

Before each start, sbx-up also copies config/skills/ into the folder sbx mounts read-only at ~/.claude/skills in every sandbox (~/Library/Application Support/com.docker.sandboxes/sandboxes/agent-skills on the Mac, not the Mac's own ~/.claude/skills). Only changed skills are copied; bin/install-skills does the same by hand.

sbx-up kit copies the template into a project's .sbx-kits/ and leaves mixins the project already has alone.

Claude Code signs in with /login inside the sandbox (the proxy keeps the real tokens on the host) or with an API key stored once on the host: sbx secret set anthropic.

Project additions

Copy project-template/.sbx-kits/ into a project with sbx-up kit. Each .sbx-kits/<name>/<name>.yaml is a v3 mixin: allow-listed hosts, install commands and files, and optionally a <name>.dockerfile for tools that are better built once. See project-template/README.md.

Changing the bases

shell-base/shell-base.dockerfile and shell-base/shared/ (copies of config/ and keys/, because a kit can only use files inside its own directory) are generated from shell-base/template.yaml and tools/*.dockerfile. After editing any of those, or config/, run python3 scripts/generate_dockerfile.py.

Background and open points: docs/kits-v3-migration.md.

About

Templates for docker sandbox

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages