From 2655b467f17f8821b90bb543fe0c2e3963e90cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Wed, 30 Sep 2026 14:59:41 +0000 Subject: [PATCH 1/2] docs: distinguish the ${WORKDIR} placeholder from the WORKSPACE_DIR variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kit authors mix up three things that share a word: the v2 ${WORKDIR} placeholder that is replaced only inside setup.files content, the WORKSPACE_DIR environment variable the runtime sets in the container, and the image's Dockerfile WORKDIR. Name all three where setup.files is documented, say that WORKDIR is not an environment variable, and note that v3 kits have no placeholder and read the variable through kit.env in lifecycle files instead. Refs docker/sbx-releases#570 Co-Authored-By: Claude Sonnet 5 Signed-off-by: Manuel de la Peña --- .../ai/sandboxes/customize/author/_index.md | 4 ++++ .../manuals/ai/sandboxes/customize/kits-v2.md | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/content/manuals/ai/sandboxes/customize/author/_index.md b/content/manuals/ai/sandboxes/customize/author/_index.md index c0c4d0d203c..f83a7c51c09 100644 --- a/content/manuals/ai/sandboxes/customize/author/_index.md +++ b/content/manuals/ai/sandboxes/customize/author/_index.md @@ -176,6 +176,10 @@ for setup examples and the upstream [lifecycle definition](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/capabilities/com.docker.sandbox/lifecycle@1.md) for the fields. +Lifecycle `files` content can read the same variables through +`${{ kit.env.NAME }}`, for example `${{ kit.env.WORKSPACE_DIR }}` for the +workspace path. Plain `$VAR` and `${VAR}` stay literal in the written file. + ## Set workload compute requirements Set the workload's default CPU and memory allocation with the diff --git a/content/manuals/ai/sandboxes/customize/kits-v2.md b/content/manuals/ai/sandboxes/customize/kits-v2.md index fb19b36087a..a18307de8fe 100644 --- a/content/manuals/ai/sandboxes/customize/kits-v2.md +++ b/content/manuals/ai/sandboxes/customize/kits-v2.md @@ -475,6 +475,7 @@ Runs synchronously when a kit is applied, either during sandbox creation or through `sbx kit add`. Shell strings are passed to `sh -c`. Kit install commands start in the template image's configured `WORKDIR`. +The workspace path is available as the `WORKSPACE_DIR` environment variable. Docker-provided templates use `/home/agent/workspace`, which isn't necessarily the primary workspace in a direct-mounted or clone-mode sandbox. Don't rely on the current directory to locate workspace files. Use absolute paths for bundled @@ -521,7 +522,7 @@ Files written at sandbox start, with runtime substitution. | Field | Default | Description | | --------------- | -------- | --------------------------------------------------------- | | `path` | — | Absolute container path. | -| `content` | — | File content. `${WORKDIR}` expands to the workspace path. | +| `content` | — | File content. The literal `${WORKDIR}` is replaced with the workspace path when the sandbox is created. | | `mode` | `"0644"` | File permissions in octal. | | `onlyIfMissing` | `false` | Skip if the file already exists. | @@ -530,6 +531,21 @@ path must be writable by that user. To write to a root-owned path such as `/etc`, use an `install` command, which runs as root by default. Set ownership in the install command if the agent needs to modify the file later. +`${WORKDIR}` is a placeholder, not an environment variable. It is replaced +only inside `content`, never in `path` or in commands. Three names look +alike and mean different things: + +| Name | What it is | Where it applies | +| --------------- | ------------------------------------------------------------- | ----------------------------------------------- | +| `${WORKDIR}` | Placeholder replaced with the workspace path at creation | `setup.files[].content` only | +| `WORKSPACE_DIR` | Environment variable set by the runtime to the workspace path | `install` and `startup` commands, and the agent | +| `WORKDIR` | The template image's Dockerfile working directory | Where commands start, see [install](#install) | + +Read `$WORKSPACE_DIR` in commands and scripts. There is no `WORKDIR` +environment variable in the sandbox. V3 kits have no `${WORKDIR}` +placeholder; lifecycle `files` content expands `${{ kit.env.WORKSPACE_DIR }}` +instead, and `$VAR` stays literal in the file. + ### Shell initialization and service logs With Docker templates, append shell initialization to From 42c38b442902fef3de945ef67c508eedf4cf8987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20de=20la=20Pe=C3=B1a?= Date: Fri, 2 Oct 2026 12:06:09 +0000 Subject: [PATCH 2/2] docs: lead with what kit authors write, then when it is substituted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review feedback on the WORKDIR / WORKSPACE_DIR clarification: the pages now open with what to write in generated files versus shell commands and only then explain when substitution happens. The v3 page gives generated files their own subsection, names container environment variables as what kit.env reads, and says unsubstituted references are written unchanged. The v2 page states the placeholder once, qualifies that shell syntax in startup commands expands only under a shell, moves the v3 comparison to the migration section, and narrows the WORKDIR claim to what a Dockerfile WORKDIR does not define. Related: docker/sbx-releases#570 Co-Authored-By: Claude Sonnet 5 Signed-off-by: Manuel de la Peña --- .../ai/sandboxes/customize/author/_index.md | 14 ++++++-- .../manuals/ai/sandboxes/customize/kits-v2.md | 32 ++++++++++--------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/author/_index.md b/content/manuals/ai/sandboxes/customize/author/_index.md index f83a7c51c09..dbf55549fcc 100644 --- a/content/manuals/ai/sandboxes/customize/author/_index.md +++ b/content/manuals/ai/sandboxes/customize/author/_index.md @@ -176,9 +176,17 @@ for setup examples and the upstream [lifecycle definition](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/capabilities/com.docker.sandbox/lifecycle@1.md) for the fields. -Lifecycle `files` content can read the same variables through -`${{ kit.env.NAME }}`, for example `${{ kit.env.WORKSPACE_DIR }}` for the -workspace path. Plain `$VAR` and `${VAR}` stay literal in the written file. +### Generated files + +In lifecycle `files` content, write `${{ kit.env.NAME }}` to insert a +container environment variable. For example, write +`${{ kit.env.WORKSPACE_DIR }}` for the workspace path. Plain `$VAR` and +`${VAR}` are written unchanged, without substituting their values. In hook +commands, use shell syntax such as `$WORKSPACE_DIR` instead. + +Docker Sandboxes substitutes `${{ kit.env.NAME }}` once, when it creates the +sandbox. `kit.env` reads the final container environment, independently of a +hook's `env` list. ## Set workload compute requirements diff --git a/content/manuals/ai/sandboxes/customize/kits-v2.md b/content/manuals/ai/sandboxes/customize/kits-v2.md index a18307de8fe..0d8476ed558 100644 --- a/content/manuals/ai/sandboxes/customize/kits-v2.md +++ b/content/manuals/ai/sandboxes/customize/kits-v2.md @@ -475,7 +475,6 @@ Runs synchronously when a kit is applied, either during sandbox creation or through `sbx kit add`. Shell strings are passed to `sh -c`. Kit install commands start in the template image's configured `WORKDIR`. -The workspace path is available as the `WORKSPACE_DIR` environment variable. Docker-provided templates use `/home/agent/workspace`, which isn't necessarily the primary workspace in a direct-mounted or clone-mode sandbox. Don't rely on the current directory to locate workspace files. Use absolute paths for bundled @@ -489,7 +488,9 @@ assets from `files/home/`. ### startup -Runs at every sandbox start. String array, not interpreted by a shell. +Runs at every sandbox start. String array, not interpreted by a shell. A +`$WORKSPACE_DIR` reference in the array is passed unchanged. To expand it, run +the command through a shell, for example `["sh", "-c", "..."]`. | Field | Default | Description | | ------------- | -------- | ----------------------------------- | @@ -522,7 +523,7 @@ Files written at sandbox start, with runtime substitution. | Field | Default | Description | | --------------- | -------- | --------------------------------------------------------- | | `path` | — | Absolute container path. | -| `content` | — | File content. The literal `${WORKDIR}` is replaced with the workspace path when the sandbox is created. | +| `content` | — | File content. Write `${WORKDIR}` for the workspace path. | | `mode` | `"0644"` | File permissions in octal. | | `onlyIfMissing` | `false` | Skip if the file already exists. | @@ -531,20 +532,20 @@ path must be writable by that user. To write to a root-owned path such as `/etc`, use an `install` command, which runs as root by default. Set ownership in the install command if the agent needs to modify the file later. -`${WORKDIR}` is a placeholder, not an environment variable. It is replaced -only inside `content`, never in `path` or in commands. Three names look -alike and mean different things: +Write `${WORKDIR}` in `content` and `$WORKSPACE_DIR` in commands. Three names +look alike and mean different things: -| Name | What it is | Where it applies | -| --------------- | ------------------------------------------------------------- | ----------------------------------------------- | -| `${WORKDIR}` | Placeholder replaced with the workspace path at creation | `setup.files[].content` only | -| `WORKSPACE_DIR` | Environment variable set by the runtime to the workspace path | `install` and `startup` commands, and the agent | -| `WORKDIR` | The template image's Dockerfile working directory | Where commands start, see [install](#install) | +| Name | What it is | Where it applies | +| --------------- | ------------------------------------------------------------- | ------------------------------------------------ | +| `${WORKDIR}` | Placeholder for the workspace path | `setup.files[].content` only | +| `WORKSPACE_DIR` | Environment variable set by the runtime to the workspace path | Shell commands, and the agent | +| `WORKDIR` | The template image's Dockerfile working directory | Where commands start, see [install](#install) | -Read `$WORKSPACE_DIR` in commands and scripts. There is no `WORKDIR` -environment variable in the sandbox. V3 kits have no `${WORKDIR}` -placeholder; lifecycle `files` content expands `${{ kit.env.WORKSPACE_DIR }}` -instead, and `$VAR` stays literal in the file. +The runtime replaces `${WORKDIR}` when it creates the sandbox, only inside +`content`, never in `path` or in commands. `WORKSPACE_DIR` is an environment +variable, so a `$WORKSPACE_DIR` reference expands only when a shell runs the +command. `install` strings run through `sh -c`. `startup` arrays run without a +shell. A Dockerfile `WORKDIR` doesn't define an environment variable. ### Shell initialization and service logs @@ -808,6 +809,7 @@ content from sandbox initialization, and declare runtime capabilities: | Automatic `files/home/` and `files/workspace/` injection | Dockerfile `COPY`, with lifecycle hooks for destinations provided by runtime mounts | | `permissions.network` and `credentials` | Network-policy and credential capabilities | | `agentInstructions` | Agent-context capability | +| `${WORKDIR}` in `setup.files[].content` | `${{ kit.env.WORKSPACE_DIR }}` in lifecycle [`files` content](/manuals/ai/sandboxes/customize/author/_index.md#generated-files) | Follow the [v3 authoring guidance](/manuals/ai/sandboxes/customize/author/_index.md) when converting runtime setup and capability declarations.