Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions content/manuals/ai/sandboxes/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,158 @@ secrets so they're available to any sandbox the CI runner creates:
$ echo "$ANTHROPIC_API_KEY" | sbx secret set -g anthropic
$ echo "$GITHUB_TOKEN" | sbx secret set -g github
```

## Sandbox environments

> [!NOTE]
> `sbx env` is experimental. The command interface and file format may change
> in future releases.

A sandbox _environment file_ describes a sandbox configuration in code —
agent type, kits, workspace, secrets, ports, and resource limits. Check one
into your repository and every team member can launch an identical sandbox
with a single command, without repeating the same `sbx run` flags. Kits and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Borderline hedge phrase: 'with a single command'

"With a single command" is a mild ease-of-use claim, similar to "simply" or "easily," which the style guide discourages. While it's technically factual (one command is run), phrasing it this way emphasizes ease rather than describing the mechanism.

Suggested rewrite:

Check one into your repository and every team member can run sbx env run, without repeating the same sbx run flags.

environment files compose naturally: use a shared base configuration plus
kits that install the exact tools a project needs.

The environment file doesn't need to live next to the workspace. You can
place it anywhere and point `workspace.path` at the target directory:

```yaml
# .sbxenv.yaml
schemaVersion: "1"
name: docs-env
agent: claude

workspace:
path: $HOME/src/github.com/docker/docs
clone: true

kits:
- "git+https://github.com/docker/sbx-kits-contrib.git#dir=vale"
- "git+https://github.com/docker/sbx-kits-contrib.git#dir=git-ssh-sign"
- "git+https://github.com/docker/sbx-kits-contrib.git#dir=github-ssh"

secrets:
github:
command: gh auth token

ports:
- sandbox: 1313
host: 1313
```

### Commands

| Command | Description |
| -------------------------- | --------------------------------------------------------------------------------- |
| `sbx env run [PATH...]` | Provisions the environment if it doesn't exist, then opens an interactive session |
| `sbx env create [PATH...]` | Provisions without attaching; for scripts and CI |
| `sbx env rm [PATH...]` | Removes the sandbox and all secrets and registry credentials scoped to it |

`PATH` can be a directory (reads the `.sbxenv.yaml` inside it) or a direct
path to the file. With no argument, `sbx env` reads `.sbxenv.yaml` in the
current directory. Passing multiple paths merges the files in order — see
[Multiple files](#multiple-files).

### File reference

All fields are optional except `schemaVersion`.

```yaml
schemaVersion: "1" # required

name: my-project # sandbox name; defaults to <agent>-<workspace-basename>
agent: claude # agent type

# Workspace as a string shorthand (path only):
workspace: .

# Workspace as an object — use when the file doesn't live next to the
# workspace, or when you want clone mode:
# workspace:
# path: /path/to/workspace
# clone: true

additionalWorkspaces:
- path: ../shared-docs
readOnly: true

kits:
- ./kits/my-mixin # local path
- docker.io/myorg/my-kit:1.0.0 # image reference

env:
NODE_ENV: development # environment variables injected into the sandbox

sandboxOptions:
memory: 8g
cpus: 4
pullPolicy: always # always | missing | never
template: docker/sandbox-templates:claude
profile: my-governance-profile

secrets:
anthropic:
ref: op://Private/Anthropic/api-key # vault URI (e.g. 1Password)
refresh: 55m # re-fetch interval
github:
command: gh auth token # stdout becomes the secret value
my-token:
value: "s3cr3t" # not recommended; see note below

registries:
docker.io:
username:
command: >-
echo "https://index.docker.io/v1/" |
docker-credential-desktop get | jq -r '.Username'
secret:
command: >-
echo "https://index.docker.io/v1/" |
docker-credential-desktop get | jq -r '.Secret'
ghcr.io:
secret:
command: gh auth token

ports:
- sandbox: 8080
host: 3000 # map sandbox port 8080 to host port 3000
- sandbox: 5432
protocol: tcp # expose without a fixed host port
```

> [!WARNING]
> Avoid `secrets.<name>.value` for real credentials. The value is plaintext
> and visible to anyone with read access to the file. Use `ref` (vault URI)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Parentheses in warning callout: '(vault URI)'

The Docker style guide says to avoid parentheses in technical documentation as they reduce readability. The phrase "ref (vault URI)" should be rewritten without parentheses.

Suggested rewrite:

Use ref for vault URIs or command instead.

> or `command` instead.

### Multiple files

`sbx env run` accepts multiple paths and deep-merges them in order. Later
files override scalar values and lists concatenate, following the same

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Verify merge semantics claim matches actual behavior

The text states "Later files override scalar values and lists concatenate, following the same semantics as Docker Compose's multiple -f files."

Docker Compose's list merge behavior is nuanced — for many keys, lists are overridden (not concatenated) depending on the key. If sbx env behavior differs from Compose in any way, this comparison could mislead users. Worth verifying the claim is accurate, and if the semantics differ from Compose's actual behavior, consider describing them directly rather than by analogy.

semantics as Docker Compose's multiple `-f` files:

```console
$ sbx env run base.sbxenv.yaml local.sbxenv.yaml
```

A common pattern is to commit a `base.sbxenv.yaml` with shared configuration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] Meta-commentary: 'A common pattern is to'

The phrase "A common pattern is to" is meta-commentary — it adds no informational value and should be replaced with a direct statement. The Docker style guide flags this alongside phrases like "It's worth noting that" and "Keep in mind that."

Suggested rewrite:

Commit a base.sbxenv.yaml with shared configuration and add local.sbxenv.yaml to .gitignore for personal overrides — a different workspace path, additional secrets, or adjusted resource limits.

and add `local.sbxenv.yaml` to `.gitignore` for personal overrides — a different
workspace path, additional secrets, or adjusted resource limits.

### Variable interpolation

The file supports shell-style variable expansion before parsing:

```yaml
workspace:
path: $HOME/src/myproject

secrets:
my-token:
value: ${MY_TOKEN} # fails to parse if MY_TOKEN is unset
# value: ${MY_TOKEN:-fallback} # uses "fallback" if MY_TOKEN is unset
```

Use `$$` to include a literal `$`.