当你把一个工具打包成 Kit 时,要尽量让它在哪里都能用。这些模式讲解如何包含它所需的访问权限,如何为每个沙箱准备好它,以及如何在不让团队自己拼装环境的前提下给他们实用的选项。
把运行时访问留在工具身边
把工具的网络规则和凭据申请留在安装它的那个 Mixin 里。例如,一个 Claude Code Mixin 可以打包可执行文件、允许访问 Anthropic API,并申请 API 密钥。当你把它加到另一个工作负载时,这些需求仍然跟着这个工具。
用户仍然需要提供凭据并批准访问。完整示例请参阅 构建工具 Mixin。
发布开发服务
对于在本地沙箱中启动开发服务器的 Kit,可以申请一个自动分配的宿主端口,这样用户无需逐次批准端口发布就能访问该服务。把这项授权加到 Kit 描述符中,并在创建沙箱时包含该 Kit:
capabilities:
- type: com.docker.sandbox/api@1
config:
operation: ports.publish
approval: none当服务监听 8080 端口时,在沙箱内发起这个请求:
$ curl --noproxy '*' --max-time 60 --fail-with-body \
-H 'Content-Type: application/json' \
--data '[{"sandbox_port":8080}]' \
"${HTTP_PROXY%/}/_sbx/api/ports"响应会给出分配到的 host_ip 和 host_port。由于省略了 host_port,宿主绑定仅监听回环地址,并使用一个临时端口。沙箱停止后它就会消失,下次启动也不会恢复。
把构建工具排除在 Mixin 之外
在一个 Dockerfile 阶段中构建工具,然后把可执行文件复制到一个空阶段中。这样每个沙箱都只拿到这个工具,不会同时拿到它的编译器和源码:
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: mixin
provides: ["gojq@0.12.17"]
build: |
FROM golang:1.25 AS build
RUN CGO_ENABLED=0 go install github.com/itchyny/gojq/cmd/gojq@v0.12.17
FROM scratch
COPY --from=build /go/bin/gojq /usr/local/bin/gojqCGO_ENABLED=0 构建出的 gojq 不依赖工作负载的 C 库。FROM scratch 让最后一个阶段从空开始,因此它只包含你复制进去的那个二进制文件。provides 条目告诉其他 Kit 这个 Mixin 安装的是哪个 gojq 版本。
合并 Kit 之后再运行安装步骤
有些安装步骤需要工作负载中的工具或文件。能放进 Mixin 的先放进去,然后用 install 钩子在所有 Kit 的文件都到位之后完成剩余安装。例如,在 Mixin 中带上一张内部证书颁发机构(CA)证书,并在工作负载的信任库中注册它:
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: mixin
build: |
FROM scratch
COPY internal-ca.crt /usr/local/share/ca-certificates/team-internal-ca.crt
capabilities:
- type: com.docker.sandbox/lifecycle@1
config:
install:
- command: update-ca-certificates
user: "0"把你的 PEM 编码的 CA 证书保存为描述符旁边的 internal-ca.crt,并与提供 update-ca-certificates 的工作负载一起使用这个 Mixin,例如 Docker 的 shell Kit。该钩子在所有 Kit 文件就位之后、智能体启动之前,以 root 身份更新工作负载的信任库。
$ sbx run docker.io/docker/sbx-kit-shell:1.0.0 --kit ./internal-ca在存储挂载之后再初始化它
在某个路径挂载存储会隐藏镜像中已有的文件。要给工具一些初始数据,把这些数据放在镜像中的其他位置,然后在 install 钩子里把它复制到挂载目录。先检查目标文件是否存在,这样能保留用户已经做过的修改:
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: mixin
build: |
FROM scratch
COPY defaults.json /usr/share/company-cli/defaults.json
capabilities:
- type: com.docker.sandbox/volume@1
config:
path: /home/agent/.company-cli
size: 1g
- type: com.docker.sandbox/lifecycle@1
config:
install:
- command: |
set -eu
if [ ! -e /home/agent/.company-cli/config.json ]; then
chown 1000:1000 /home/agent/.company-cli
install -o 1000 -g 1000 -m 0644 /usr/share/company-cli/defaults.json /home/agent/.company-cli/config.json
fi
user: "0"把你工具的初始配置保存为描述符旁边的 defaults.json。使用带 chown 和 install 的工作负载,例如 Docker 的 shell Kit。该钩子让目录和配置文件对智能体可写。如果卷中已经有配置文件,钩子会保留其中的内容不变。
配置卷
在本地沙箱中,持久卷(volume@1 且 tmpfs: false)会让数据在重启、Kit 更新和沙箱删除后依然保留。当沙箱名称、Kit 来源和卷路径都相同时,Docker Sandboxes 会重新挂载同一个卷。改动卷路径会得到独立的存储,因此当你希望用户保留数据时,请在各个 Kit 版本之间保持路径稳定。
对于已发布的 Kit,更改标签或 digest 不会改变 Kit 来源。对于 Git 来源,仓库和 Kit 子目录必须保持不变;对于本地来源,源目录必须保持不变。tmpfs 的内容会在沙箱停止时被丢弃。
这个示例分配 1g 空间。如果省略 size,sbx 会分配 512m。
当你的工具需要特定的属主或权限时,像这个示例一样使用 install 钩子。卷被复用时,要让初始化过程保留已有的文件和权限。存储选项请参阅上游的 卷定义。
如果要把初始文件复制进已挂载的工作区,改用 WORKSPACE_DIR 作为目标路径,并 在钩子的环境中声明它。
发布固定组件并提供可配置选项
为团队选定兼容的智能体和工具版本,然后把它们发布为一个集合。为那些用户无需替换组件就能修改的设置暴露参数,比如模型或 linter 模式。把版本选择固定在已发布的镜像中。
参数语法和约束请参阅 配置组件参数。