docker-sandboxes-lifecycle
Use this skill when creating, running, reattaching to, listing, stopping, or removing Docker Sandboxes (the standalone `sbx` CLI that runs AI coding agents in isolated microVMs), even if the user just says they want to "run claude in a sandbox", "isolate an agent from my repo", "
Install
npx skills add https://github.com/docker/skills/tree/main/skills/docker-sandboxes-lifecycle
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install docker-skills@llmmart
git clone https://github.com/docker/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole docker/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Docker Sandboxes: Local Lifecycle & Workspace Isolation
Overview
Docker Sandboxes (sbx) runs an AI coding agent inside an isolated microVM with
its own filesystem, network, and Docker daemon. This skill owns the local
sandbox lifecycle — creating, reattaching to, listing, stopping, and removing
sandboxes — and the workspace isolation choice (direct bind mount vs.
--clone). It does not cover network policy, credentials, sbxenv.yaml, or
kit authoring — see Related skills.
When to use this skill
Activate this skill when:
- The user wants to start, reattach to, stop, or remove a local
sbxsandbox. - The user wants an agent to work on a repository without giving it a
writable bind mount of the host working tree (
--clone). - The user wants extra read-only (or write-restricted) workspaces mounted alongside the primary one.
- The user is copying files between host and sandbox, publishing a sandbox
port, or running an ad-hoc command inside a sandbox (
sbx exec). - The user wants to clean up stopped sandboxes (
sbx prune) or remove a specific one (sbx rm), with the destructive consequences understood.
Do not use this skill when
Do not use this skill when:
- The task is running
docker agent run --sandboxor managing itsdocker agent sandboxallowlist — usedocker-agent-run. If the CLI is unclear, establish whether the user runs Docker Agent or standalonesbxbefore choosing commands. - The task is about what a sandbox can reach on the network or which
credentials it uses — use
docker-sandboxes-network-credentials. - The task is authoring or running a declarative
sbxenv.yamlfile — usedocker-sandboxes-env. - The task is authoring, packaging, signing, or composing a kit
spec.yaml— usedocker-sandboxes-kits. - The task is about
sbx --cloud(Docker Cloud Sandboxes) — out of scope for this skill set, which covers the local daemon only.
Core guidance
Creating vs. running
- Use
sbx run AGENT [PATH...]to create-if-needed and attach in one step. Usesbx create AGENT [PATH...]to create without attaching, thensbx run --name SANDBOXto attach later. Pass--detached/-dtosbx runto print the sandbox ID and exit without an interactive session.sbx run shell # create (if needed) and attach, cwd mounted sbx create shell . # create only, cwd mounted, do not attach sbx run --name my-sandbox # reattach later AGENTis a built-in name (claude,codex,cursor,devin,docker-agent,gemini,opencode,shell) or a sandbox kit reference (local directory, ZIP, git, or OCI). A relative local kit reference MUST be an explicit path (./my-kit, a parent-relative.zippath) — a baremy-kitis read as an agent/sandbox name, never a directory beside the cwd.- Omitting the path is not the same for every subcommand.
sbx run claudewith no path mounts the current directory.sbx create claudewith no path mounts nothing at all — the agent then works only in the container's own filesystem. Always pass a path explicitly withsbx createif you intend to give the agent a workspace. - Prefer
--nameto reattach; a bare positional name still works but is deprecated.sbx run --name NAME(agent positional optional, read from the sandbox's own spec) is the recommended form. A baresbx run NAME— a positional that is neither a known agent nor an explicit kit reference — is still accepted as a legacy re-attach shorthand, but prints a deprecation warning ("sbx run NAMEis deprecated; usesbx run --name NAMEinstead") and may be removed in a future release. Always write--nameexplicitly rather than relying on the legacy form.sbx run --name existing-sandbox # reattach, agent read from spec sbx run claude --name existing-sandbox # reattach, verify expected agent
Workspace isolation: bind mount vs. --clone
- Default (bind mount): the workspace path is mounted read/write inside the sandbox at the same path as on the host. The agent can write directly to your working tree.
--clone(creation-time only): the agent runs against a private in-container clone of the host Git repository. The host repo is mounted read-only; the agent's commits land in the in-container clone and are reachable from the host via asandbox-<name>git remote — fetch or pull from it to bring commits back.sbx create --clone --name demo claude . # on the host, later: git fetch sandbox-demo--clonehas real preconditions, checked at creation time, and fails loudly if any is unmet:- an explicit
PATHmust be given (there must be a workspace to clone from); - that path must be inside a Git repository;
- it must NOT be a Git worktree (the in-container clone cannot follow a
worktree's
.gitpointer out to a common dir elsewhere); - its
.gitmust be a real directory, not a file (a submodule or a--separate-git-dirsetup points.gitelsewhere, which the read-only source mount would not include).
- an explicit
--cloneonsbx runwhen reattaching is a no-op ONLY on a sandbox already created in clone mode — it re-validates nothing new and simply keeps running the existing in-container clone. Passing--clonewhile reattaching to a sandbox that was created without it (a plain bind-mounted sandbox) is not a silent no-op: it fails with an error telling you to recreate the sandbox withsbx create --clone .... Neither form can convert an existing sandbox's mode after creation.- Removing or pruning a clone-mode sandbox permanently discards every
commit the agent made that was never fetched back to the host — the
in-container clone lives on the sandbox's own filesystem and is deleted
with it. Before removing a clone-mode sandbox, fetch its work first:
Fetching populates two refspecs: the ordinarygit fetch sandbox-demorefs/remotes/sandbox-demo/*(deleted along with the remote when the sandbox is removed) and a survivor copy atrefs/sandboxes/demo/*(outside the remote namespace, so it is not deleted when the remote goes). Recover a branch from the survivor copy after removal with:git branch <local-name> refs/sandboxes/demo/<branch>sbx rm/sbx pruneprint this warning automatically for any clone-mode sandbox they are about to remove; read it before confirming, don't suppress it with--forceout of habit. - Additional workspaces are extra positional paths after the first. Append
:roto mount one read-only.:roblocks writes, not reads — the sandbox can still read every file under a:romount; it is not a way to hide sensitive content, only to stop the sandbox from modifying it. A read-only argument may name a single file rather than a directory, holding just that one path out of reach for writes inside a workspace the sandbox can otherwise write.
Never mount a secrets/credentials file this way (sbx run claude . /path/to/docs:ro:roor otherwise) — a read-only mount still lets the sandbox (and, through it, the proxy-less agent process) read the secret in the clear. Use the credential store instead; seedocker-sandboxes-network-credentials.
Reattaching, stopping, and removing
sbx lslists sandboxes with agent, status, published ports, and workspace (--json,-q/--quietfor scripting).sbx stop SANDBOX [SANDBOX...]stops without removing; state is retained and the sandbox restarts withsbx run --name.sbx rm [SANDBOX...] [--all] [--force]removes sandboxes, their containers, Git worktrees, state, and sandbox-scoped secrets. This cannot be undone, and for a clone-mode sandbox it discards every unfetched commit (see above). Only use--forcewhen you have already reviewed what will be destroyed and consented — for scripted teardown of resources this session itself created and uniquely named, not as a default habit.sbx prune [--dry-run] [--filter until=VALUE] [--force]removes only stopped sandboxes — a running sandbox is never touched — but this is still a destructive, irreversible bulk removal: every matching stopped sandbox's state, secrets, and (for clone-mode sandboxes) any unfetched commits are gone. Always preview with--dry-runfirst and read the clone-commit warning it prints before removing for real; do not pass--forceas a default.- Current source flag is
--filter until=VALUE, notsince=.VALUEmay be an RFC 3339 timestamp, a Unix timestamp, or a Go duration relative to now (e.g.until=168hkeeps anything stopped within the last week — i.e. prunes what stopped before that point). This is a source-only behavior at the pinned commit that differs from some installed builds: an older installedsbxmay still advertise--filter since=DURATIONas a legacy alias; preferuntil=and treatsince=as legacy-only if your installed--helpoutput does not showuntil=.
sbx prune --dry-run --filter until=168h # after reviewing the dry-run output and any clone-commit warnings: sbx prune --filter until=168h- Current source flag is
Copying files and running ad-hoc commands
sbx cp SRC DSTcopies between host and sandbox; exactly one side must beSANDBOX:PATH. Copying between two sandboxes is not supported.sbx cp ./config.json my-sandbox:/home/agent/ sbx cp my-sandbox:/home/agent/output.log ./sbx exec [flags] SANDBOX COMMAND [ARG...]runs a command in a sandbox (starting it first if stopped); flags mirrordocker exec(-it,-d,-u,-w,-e,--env-file,--privileged).sbx exec -it my-sandbox bash sbx exec -u root my-sandbox apt-get updatesbx ports SANDBOX [--publish SPEC] [--unpublish SPEC]manages published ports after creation;-p/--publishonsbx create/sbx runonly takes effect when the sandbox is created, not on reattach.
Sizing and naming
--cpus(0 = auto: all host CPUs) and--memory/-m(default 50% of host memory, clamped 512 MiB–32 GiB) are create-time-only knobs.--namesets the sandbox name (default<agent>-<workdir>); at least two characters, starting with a letter or number, letters/numbers/hyphens/ periods only, at most 63 ASCII characters, ending in a letter or number;defaultis reserved.
Related skills
For
docker agent run --sandboxanddocker agent sandboxcommands, usedocker-agent-run.For network egress policy and service/registry credentials, use
docker-sandboxes-network-credentials.For declarative, checked-in
sbxenv.yamlenvironments that wrap this same create/run/rm lifecycle, usedocker-sandboxes-env.For authoring or composing the kit
spec.yamlanAGENTreference can point to, usedocker-sandboxes-kits.
References
references/sources.md— provenance for every rule above (help captures, source paths, docs URLs).
Assets
- None.
Checks
checks/verification.md— Verification runbook for sandbox lifecycle commands (unexecuted runbook; run manually with an isolated--app-name, never with--forceexcept consented cleanup of the runbook's own uniquely-named test sandboxes).
Files (skills)
-
agents
-
openai.yaml 474 B
interface: display_name: 'Docker Sandboxes: Local Lifecycle & Workspace Isolation' short_description: Create, reattach to, and tear down local `sbx` sandboxes; choose workspace bind-mount vs --clone isolation. default_prompt: Use this skill when running, reattaching to, or cleaning up local Docker Sandboxes (`sbx run`/`create`/`ls`/`stop`/`rm`/`prune`), or choosing between a bind-mounted workspace and `--clone` isolation. policy: allow_implicit_invocation: true
-
-
checks
-
verification.md 4.4 KB
# Verification Runbook for local sandbox lifecycle commands User-run integration checks; not executed during skill generation. Prerequisites: standalone `sbx`, Git, a supported local runtime, and an existing Docker login. `sbx login` changes shared authentication, not just the isolated test app. Run from the skill directory in one shell; negative checks intentionally fail. Never use a real repository or production credentials for these checks. ## 1. Create an isolated test session and disposable Git repository ```bash APP="l-$(date +%s)-$$" # unique suffix, at most 20 characters WORK=$(mktemp -d) REPO="$WORK/repo" git init -q -b main "$REPO" git -C "$REPO" -c user.name=Test -c user.email=test@example.invalid commit -q --allow-empty -m initial sbx --app-name "$APP" version sbx --app-name "$APP" policy init balanced ``` Pass: standalone version is displayed and policy is initialized for this fresh app. Every following `sbx` command must retain this same `--app-name`. If inherited `DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND` causes plugin-wrapper output, unset it before invoking standalone `sbx`. ## 2. Compare create-without-path and run-with-a-workspace ```bash sbx --app-name "$APP" create --name no-mount-check shell sbx --app-name "$APP" run --name mount-check -d shell "$REPO" sbx --app-name "$APP" ls --json sbx --app-name "$APP" run --name mount-check -d sbx --app-name "$APP" ls --json ``` Pass: `no-mount-check` has no workspace; `mount-check` has `$REPO`. Reusing `--name mount-check` does not create a third sandbox. Detached run does not open an interactive agent session. ## 3. Check clone-mode creation and reattachment ```bash sbx --app-name "$APP" create --clone --name clone-check shell "$REPO" git -C "$REPO" remote -v sbx --app-name "$APP" run --clone --name clone-check -d sbx --app-name "$APP" run --clone --name no-mount-check -d ``` Pass: the remote `sandbox-clone-check` exists; reattaching to `clone-check` succeeds; the last command fails because `no-mount-check` was not created in clone mode. The disposable repository has a real `.git` directory and is neither a linked worktree nor a submodule. ## 4. Preserve fetched clone commits before removal ```bash sbx --app-name "$APP" exec clone-check git -c user.name=Test -c user.email=test@example.invalid commit --allow-empty -m clone-check-commit git -C "$REPO" fetch sandbox-clone-check git -C "$REPO" log --oneline -1 refs/remotes/sandbox-clone-check/main sbx --app-name "$APP" rm --force clone-check git -C "$REPO" rev-parse --verify refs/remotes/sandbox-clone-check/main git -C "$REPO" log --oneline -1 refs/sandboxes/clone-check/main ``` Pass: the first log shows `clone-check-commit`. After this consented removal, `rev-parse` fails (the ordinary remote ref was removed) but the survivor ref still shows that commit. Exec uses the sandbox's recorded workspace, not an assumed `/workspace`. Unfetched commits would be lost on removal. ## 5. Confirm read-only mounts remain readable ```bash mkdir "$WORK/docs" printf 'readable-content\n' > "$WORK/docs/notes.txt" sbx --app-name "$APP" run --name ro-check -d shell "$REPO" "$WORK/docs:ro" sbx --app-name "$APP" exec ro-check cat "$WORK/docs/notes.txt" sbx --app-name "$APP" exec ro-check sh -c 'echo x >> "$1"' sh "$WORK/docs/notes.txt" ``` Pass: reading succeeds; writing fails with a read-only/permission error. Use harmless test content, never a real secrets file. ## 6. Preview prune candidates and its age filter ```bash sbx --app-name "$APP" run --name prune-keep -d shell "$REPO" sbx --app-name "$APP" create --name prune-drop shell "$REPO" sbx --app-name "$APP" stop prune-drop sbx --app-name "$APP" prune --dry-run --json sbx --app-name "$APP" prune --dry-run --json --filter until=168h ``` Pass: the unfiltered preview includes `prune-drop` and excludes running `prune-keep`; other stopped test sandboxes may also appear. The age-filtered preview is empty because this app's sandboxes were created moments ago, not stopped more than a week ago. Neither preview removes anything. ## 7. Clean up only this disposable session ```bash sbx --app-name "$APP" rm --force no-mount-check mount-check ro-check prune-keep prune-drop sbx --app-name "$APP" daemon stop rm -rf "$WORK" ``` Pass: these test sandboxes are removed and their isolated daemon stops. The forced removals above are explicitly consented test cleanup, not defaults for normal work. If a check stopped early, inspect this app with `sbx --app-name "$APP" ls` and remove only its remaining test sandboxes first.
-
-
references
-
sources.md 4.5 KB
# Sources ## Local pinned source (repository docker/sandboxes, commit df5c96ba60484fa2c375469dbac912c205da6c37) Paths below are relative to the repository root. - `AGENTS.md` — repository-level agent instructions, isolated `--app-name` testing rule. - `README.md` — `sbx login` / `sbx run claude` quick-start; pointer to docs.docker.com/ai/sandboxes/. - `cli-plugin/commands/run.go` — `resolveCloneWorkdirForExistingSandbox` (reattach `--clone`: no-op only on an existing clone-mode sandbox; errors on a plain/bind-mounted sandbox or a legacy worktree sandbox missing its label), `warnDeprecatedRunPositionalName` (bare `sbx run NAME` prints a deprecation warning but is still accepted — `legacyPositionalAttach`), `directLookupCandidate`/`legacyPositionalAttach` wiring in `executeRun`. - `cli-plugin/commands/create.go` — `validateCloneOptions` (the four `--clone` preconditions: explicit workspace path, inside a Git repository, not a Git worktree, `.git` a real directory not a file/submodule pointer), `addCreateAgentSubcommand` (`:ro` semantics: "holds that one path out of reach inside a workspace the sandbox can otherwise write" — a write restriction, not a read restriction). - `cli-plugin/commands/rm.go` — `warnUnsavedCloneChanges` (the exact `git fetch sandbox-<name>` / `refs/remotes/sandbox-<name>/*` vs. survivor `refs/sandboxes/<name>/*` / `git branch <local> refs/sandboxes/<name>/<branch>` recovery text), `removeAll`/`removeByNameConfirmedWithSecretRemoval` (confirmation-prompt and `--force` semantics for `sbx rm`/`sbx rm --all`), `errRemovalDeclined`. - `cli-plugin/commands/root.go` — `rootFlags` (`--app-name`, hidden persistent flag, "Storagekit application name for isolated daemon instance"), `commandsWithoutDaemon`/`needDaemonAutoStart` (daemon-free commands). - `docs/yml/sbx_ls.yaml` — agent/status/published-ports/workspace listing, `--json`, and `-q`/`--quiet` (sandbox names only). - `docs/yml/sbx_stop.yaml` — stops one or more sandboxes without removing them; retains state for restart with `sbx run`. - `docs/yml/sbx_exec.yaml` — starts a stopped sandbox before execution; local exec flags `-i`, `-t`, `-d`, `-u`, `-w`, `-e`, `--env-file`, and `--privileged`. - `docs/yml/sbx_cp.yaml` — exactly one of SRC/DST must be `SANDBOX:PATH`; the other is local, and sandbox-to-sandbox copies are unsupported. - `docs/yml/sbx_ports.yaml` — lists ports or changes existing bindings with `--publish`/`--unpublish`. - `docs/yml/sbx_create.yaml` / `docs/yml/sbx_run.yaml` — `-p`/`--publish` applies at creation only; run's flag explicitly says reattach ignores it and directs users to `sbx ports`. - `docs/yml/sbx_prune.yaml` — current, pinned-source usage text: `--filter until=TIMESTAMP` ("stopped before TIMESTAMP... RFC 3339 timestamp, Unix timestamp, or Go duration relative to now, e.g. until=168h"), not `since=`. ## Captured standalone CLI help, cross-checked against an older installed build Installed `sbx` reports `v0.42.0-503-g951b7f6d7` (commit `951b7f6d7f6bb260fac15077b607109ffe8ae012`), older than the pinned source HEAD. Verified name/version with `sbx version`; captured with `sbx <cmd> --help` under an isolated `--app-name`, no daemon started. - **`sbx prune --help` differs from the pinned source**: the installed build's help still advertises `--filter since=DURATION` as the supported filter syntax. The pinned source's `docs/yml/sbx_prune.yaml` (generated from the same `--help` text at commit df5c96ba) instead documents `--filter until=VALUE` (RFC 3339 / Unix timestamp / duration). This is an explicit source-vs-installed-help difference: prefer `until=` per the pinned source, and treat `since=` as a legacy alias an older installed build may still show. - Every other command this skill covers (`create`, `run`, `ls`, `stop`, `rm`, `exec`, `cp`, `ports`) showed no source-only difference between the installed help and the pinned-source `docs/yml/*.yaml`. ## Not verified / explicitly excluded - `sbx --cloud` (Docker Cloud Sandboxes) flags appear in the generated reference as inherited options but are out of scope for this skill, which covers the local daemon only; not exercised or asserted beyond noting their existence. - No docs.docker.com URL beyond the canonical product page (https://docs.docker.com/ai/sandboxes/) is cited here: this review did not independently fetch any deeper docs.docker.com page, so no more specific URL is asserted as a source for any rule above. Every rule above traces to a repository path and/or a captured `--help` output, not to a fetched docs page.
-
-
SKILL.md 12.4 KB
--- name: docker-sandboxes-lifecycle description: Use this skill when creating, running, reattaching to, listing, stopping, or removing Docker Sandboxes (the standalone `sbx` CLI that runs AI coding agents in isolated microVMs), even if the user just says they want to "run claude in a sandbox", "isolate an agent from my repo", "give an agent its own git clone", or "clean up old sandboxes". Covers `sbx run`/`sbx create` (including the built-in agents claude, codex, cursor, devin, docker-agent, gemini, opencode, shell), workspace bind-mount vs `--clone` isolation, additional read-only workspaces, reattaching by `--name`, `sbx ls`/`stop`/`rm`/`prune`, `sbx exec`, `sbx cp`, and `sbx ports`. license: Apache-2.0 compatibility: Standalone `sbx` CLI (not the legacy `docker sandbox` plugin wrapper). Source-verified against docker/sandboxes (github.com/docker/sandboxes) @ commit df5c96ba60484fa2c375469dbac912c205da6c37. Cross-checked against an installed sbx v0.42.0-503-g951b7f6d7 (commit 951b7f6d7f6bb260fac15077b607109ffe8ae012, older than the pinned source); one source-only behavior change is called out explicitly below (`sbx prune --filter`). `docker_help` does not cover standalone `sbx` syntax. --- # Docker Sandboxes: Local Lifecycle & Workspace Isolation ## Overview Docker Sandboxes (`sbx`) runs an AI coding agent inside an isolated microVM with its own filesystem, network, and Docker daemon. This skill owns the local sandbox lifecycle — creating, reattaching to, listing, stopping, and removing sandboxes — and the workspace isolation choice (direct bind mount vs. `--clone`). It does not cover network policy, credentials, `sbxenv.yaml`, or kit authoring — see Related skills. ## When to use this skill Activate this skill when: - The user wants to start, reattach to, stop, or remove a local `sbx` sandbox. - The user wants an agent to work on a repository without giving it a writable bind mount of the host working tree (`--clone`). - The user wants extra read-only (or write-restricted) workspaces mounted alongside the primary one. - The user is copying files between host and sandbox, publishing a sandbox port, or running an ad-hoc command inside a sandbox (`sbx exec`). - The user wants to clean up stopped sandboxes (`sbx prune`) or remove a specific one (`sbx rm`), with the destructive consequences understood. ## Do not use this skill when Do not use this skill when: - The task is running `docker agent run --sandbox` or managing its `docker agent sandbox` allowlist — use `docker-agent-run`. If the CLI is unclear, establish whether the user runs Docker Agent or standalone `sbx` before choosing commands. - The task is about what a sandbox can reach on the network or which credentials it uses — use `docker-sandboxes-network-credentials`. - The task is authoring or running a declarative `sbxenv.yaml` file — use `docker-sandboxes-env`. - The task is authoring, packaging, signing, or composing a kit `spec.yaml` — use `docker-sandboxes-kits`. - The task is about `sbx --cloud` (Docker Cloud Sandboxes) — out of scope for this skill set, which covers the local daemon only. ## Core guidance ### Creating vs. running - Use `sbx run AGENT [PATH...]` to create-if-needed **and** attach in one step. Use `sbx create AGENT [PATH...]` to create without attaching, then `sbx run --name SANDBOX` to attach later. Pass `--detached`/`-d` to `sbx run` to print the sandbox ID and exit without an interactive session. ```bash sbx run shell # create (if needed) and attach, cwd mounted sbx create shell . # create only, cwd mounted, do not attach sbx run --name my-sandbox # reattach later ``` - `AGENT` is a built-in name (`claude`, `codex`, `cursor`, `devin`, `docker-agent`, `gemini`, `opencode`, `shell`) or a sandbox kit reference (local directory, ZIP, git, or OCI). A relative local kit reference MUST be an explicit path (`./my-kit`, a parent-relative `.zip` path) — a bare `my-kit` is read as an agent/sandbox name, never a directory beside the cwd. - **Omitting the path is not the same for every subcommand.** `sbx run claude` with no path mounts the **current directory**. `sbx create claude` with no path mounts **nothing at all** — the agent then works only in the container's own filesystem. Always pass a path explicitly with `sbx create` if you intend to give the agent a workspace. - **Prefer `--name` to reattach; a bare positional name still works but is deprecated.** `sbx run --name NAME` (agent positional optional, read from the sandbox's own spec) is the recommended form. A bare `sbx run NAME` — a positional that is neither a known agent nor an explicit kit reference — is still **accepted** as a legacy re-attach shorthand, but prints a deprecation warning ("`sbx run NAME` is deprecated; use `sbx run --name NAME` instead") and may be removed in a future release. Always write `--name` explicitly rather than relying on the legacy form. ```bash sbx run --name existing-sandbox # reattach, agent read from spec sbx run claude --name existing-sandbox # reattach, verify expected agent ``` ### Workspace isolation: bind mount vs. `--clone` - **Default (bind mount):** the workspace path is mounted read/write inside the sandbox at the same path as on the host. The agent can write directly to your working tree. - **`--clone` (creation-time only):** the agent runs against a private in-container clone of the host Git repository. The host repo is mounted **read-only**; the agent's commits land in the in-container clone and are reachable from the host via a `sandbox-<name>` git remote — fetch or pull from it to bring commits back. ```bash sbx create --clone --name demo claude . # on the host, later: git fetch sandbox-demo ``` - **`--clone` has real preconditions, checked at creation time**, and fails loudly if any is unmet: - an explicit `PATH` must be given (there must be a workspace to clone from); - that path must be inside a Git repository; - it must NOT be a Git worktree (the in-container clone cannot follow a worktree's `.git` pointer out to a common dir elsewhere); - its `.git` must be a real directory, not a file (a submodule or a `--separate-git-dir` setup points `.git` elsewhere, which the read-only source mount would not include). - **`--clone` on `sbx run` when reattaching is a no-op ONLY on a sandbox already created in clone mode** — it re-validates nothing new and simply keeps running the existing in-container clone. Passing `--clone` while reattaching to a sandbox that was created **without** it (a plain bind-mounted sandbox) is **not** a silent no-op: it fails with an error telling you to recreate the sandbox with `sbx create --clone ...`. Neither form can convert an existing sandbox's mode after creation. - **Removing or pruning a clone-mode sandbox permanently discards every commit the agent made that was never fetched back to the host** — the in-container clone lives on the sandbox's own filesystem and is deleted with it. Before removing a clone-mode sandbox, fetch its work first: ```bash git fetch sandbox-demo ``` Fetching populates two refspecs: the ordinary `refs/remotes/sandbox-demo/*` (deleted along with the remote when the sandbox is removed) and a survivor copy at `refs/sandboxes/demo/*` (outside the remote namespace, so it is **not** deleted when the remote goes). Recover a branch from the survivor copy after removal with: ```bash git branch <local-name> refs/sandboxes/demo/<branch> ``` `sbx rm`/`sbx prune` print this warning automatically for any clone-mode sandbox they are about to remove; read it before confirming, don't suppress it with `--force` out of habit. - Additional workspaces are extra positional paths after the first. Append `:ro` to mount one read-only. **`:ro` blocks writes, not reads** — the sandbox can still read every file under a `:ro` mount; it is not a way to hide sensitive content, only to stop the sandbox from modifying it. A read-only argument may name a single file rather than a directory, holding just that one path out of reach for writes inside a workspace the sandbox can otherwise write. ```bash sbx run claude . /path/to/docs:ro ``` **Never mount a secrets/credentials file this way** (`:ro` or otherwise) — a read-only mount still lets the sandbox (and, through it, the proxy-less agent process) read the secret in the clear. Use the credential store instead; see `docker-sandboxes-network-credentials`. ### Reattaching, stopping, and removing - `sbx ls` lists sandboxes with agent, status, published ports, and workspace (`--json`, `-q`/`--quiet` for scripting). - `sbx stop SANDBOX [SANDBOX...]` stops without removing; state is retained and the sandbox restarts with `sbx run --name`. - `sbx rm [SANDBOX...] [--all] [--force]` removes sandboxes, their containers, Git worktrees, state, and sandbox-scoped secrets. **This cannot be undone**, and for a clone-mode sandbox it discards every unfetched commit (see above). Only use `--force` when you have already reviewed what will be destroyed and consented — for scripted teardown of resources this session itself created and uniquely named, not as a default habit. - `sbx prune [--dry-run] [--filter until=VALUE] [--force]` removes only **stopped** sandboxes — a running sandbox is never touched — but this is still a destructive, irreversible bulk removal: every matching stopped sandbox's state, secrets, and (for clone-mode sandboxes) any unfetched commits are gone. Always preview with `--dry-run` first and read the clone-commit warning it prints before removing for real; do not pass `--force` as a default. - **Current source flag is `--filter until=VALUE`**, not `since=`. `VALUE` may be an RFC 3339 timestamp, a Unix timestamp, or a Go duration relative to now (e.g. `until=168h` keeps anything stopped within the last week — i.e. prunes what stopped *before* that point). **This is a source-only behavior at the pinned commit that differs from some installed builds**: an older installed `sbx` may still advertise `--filter since=DURATION` as a legacy alias; prefer `until=` and treat `since=` as legacy-only if your installed `--help` output does not show `until=`. ```bash sbx prune --dry-run --filter until=168h # after reviewing the dry-run output and any clone-commit warnings: sbx prune --filter until=168h ``` ### Copying files and running ad-hoc commands - `sbx cp SRC DST` copies between host and sandbox; exactly one side must be `SANDBOX:PATH`. Copying between two sandboxes is not supported. ```bash sbx cp ./config.json my-sandbox:/home/agent/ sbx cp my-sandbox:/home/agent/output.log ./ ``` - `sbx exec [flags] SANDBOX COMMAND [ARG...]` runs a command in a sandbox (starting it first if stopped); flags mirror `docker exec` (`-it`, `-d`, `-u`, `-w`, `-e`, `--env-file`, `--privileged`). ```bash sbx exec -it my-sandbox bash sbx exec -u root my-sandbox apt-get update ``` - `sbx ports SANDBOX [--publish SPEC] [--unpublish SPEC]` manages published ports after creation; `-p/--publish` on `sbx create`/`sbx run` only takes effect when the sandbox is created, not on reattach. ### Sizing and naming - `--cpus` (0 = auto: all host CPUs) and `--memory`/`-m` (default 50% of host memory, clamped 512 MiB–32 GiB) are create-time-only knobs. - `--name` sets the sandbox name (default `<agent>-<workdir>`); at least two characters, starting with a letter or number, letters/numbers/hyphens/ periods only, at most 63 ASCII characters, ending in a letter or number; `default` is reserved. ## Related skills - For `docker agent run --sandbox` and `docker agent sandbox` commands, use `docker-agent-run`. - For network egress policy and service/registry credentials, use `docker-sandboxes-network-credentials`. - For declarative, checked-in `sbxenv.yaml` environments that wrap this same create/run/rm lifecycle, use `docker-sandboxes-env`. - For authoring or composing the kit `spec.yaml` an `AGENT` reference can point to, use `docker-sandboxes-kits`. ## References - `references/sources.md` — provenance for every rule above (help captures, source paths, docs URLs). ## Assets - None. ## Checks - `checks/verification.md` — Verification runbook for sandbox lifecycle commands (unexecuted runbook; run manually with an isolated `--app-name`, never with `--force` except consented cleanup of the runbook's own uniquely-named test sandboxes). -
skill.yaml 1.2 KB
schema: v1 id: docker-sandboxes-lifecycle version: 0.1.0 title: 'Docker Sandboxes: Local Lifecycle & Workspace Isolation' description: Create, reattach to, and tear down local `sbx` sandboxes; choose workspace bind-mount vs --clone isolation. owns: - sbx-run - sbx-create - sbx-ls - sbx-stop - sbx-rm - sbx-prune - sbx-exec - sbx-cp - sbx-ports - sandbox-workspace-clone-mode use_when: - The user wants to start, reattach to, stop, or remove a local sbx sandbox. - The user wants an agent to work on a repository without a writable bind mount of the host working tree (--clone). - The user wants extra read-only workspaces mounted alongside the primary one, or wants to copy files/publish ports/exec into a sandbox. - The user wants to clean up stopped sandboxes or remove a specific one. do_not_use_when: - The task is docker agent run --sandbox or its docker agent sandbox allowlist. - The task is about sandbox network egress policy or service/registry credentials. - The task is authoring or running a declarative sbxenv.yaml file. - The task is authoring, packaging, signing, or composing a kit spec.yaml. delegates_to: - docker-agent-run - docker-sandboxes-network-credentials - docker-sandboxes-env - docker-sandboxes-kits
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.