-
Notifications
You must be signed in to change notification settings - Fork 8.4k
docs(sandboxes): add sandbox environments section (sbx env, experimental) #25487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
f4802c4
c5e7e8f
d4bce81
e40a32b
20dde9e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
| 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 " Suggested rewrite:
|
||
| > 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Docker Compose's list merge behavior is nuanced — for many keys, lists are overridden (not concatenated) depending on the key. If |
||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
|
||
| 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 `$`. | ||
There was a problem hiding this comment.
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: