构建一个 Kit,让 Claude Code 在你选择的 Linux 基础镜像上运行。你会安装这个智能体,让它能够访问 Anthropic API,并添加模型设置和给团队的说明。构建结果是 v3 工作负载 Kit,你可以在本地运行它,也可以发布给别人使用。换成其他智能体或你组织自己的基础镜像时,可以遵循同样的步骤。
本教程准备的是完整环境,从系统软件包一直到启动智能体的命令。如果你已经有合适的智能体镜像,请参阅 打包已有的智能体镜像。 要把已发布的智能体 Kit 与工具组合起来,请编写 Kit 集合。
如果你刚开始接触 Kit,请阅读编写 Kit,了解你要创建的文件。字段定义见 上游 v3 规范。
准备 Kit 目录
你需要 sbx、带 Buildx 的 Docker,以及一个 Anthropic API 密钥。在你希望智能体工作的项目旁边创建一个目录:
$ mkdir claude-team完成后的目录包含三个文件:
claude-team/
├── claude-team.yaml
├── claude-team.dockerfile
└── context.mdDockerfile 安装智能体并设置运行它的命令。称为描述符的 YAML 文件告诉 Docker Sandboxes 运行这个智能体需要什么,比如网络访问和凭据。Markdown 文件包含给智能体的说明。让 YAML 文件和 Dockerfile 在扩展名之前使用相同的名字,这样构建才能找到这两个文件。
这个 Kit 使用 v3,独立于内置的 claude Kit。你添加的任何 Mixin 也必须使用 v3。
使用你自己的基础镜像
本教程从 Red Hat Universal Base Image(UBI)9 开始。下面的步骤会添加沙箱所需的工具、用户账户和证书。你可以使用其他 Linux 镜像,包括由你组织维护的镜像。按该镜像调整软件包和账户命令,并遵循同样的 基础镜像要求。
安装系统软件包
创建 claude-team/claude-team.dockerfile,写入基础镜像和软件包:
FROM registry.access.redhat.com/ubi9/ubi:9.8
USER root
RUN dnf install -y bash ca-certificates curl-minimal git shadow-utils tar gzip \
&& dnf clean allBash 运行 shell 命令,Git 访问源码仓库,curl 使用 CA 证书发起 HTTPS 请求。其余的软件包用于创建智能体的用户账户并解包它的安装程序。你项目需要的编译器、库或其他工具,也在这里添加。
创建智能体账户
沙箱需要一个 UID 为 1000、主目录为 /home/agent 的非 root agent 用户。把下面内容追加到 Dockerfile,创建该账户以及它的工作区、配置和状态目录:
RUN groupadd --gid 1000 agent \
&& useradd --uid 1000 --gid 1000 --create-home --shell /bin/bash agent \
&& mkdir -p /home/agent/workspace /home/agent/.local/bin \
/home/agent/.local/share /home/agent/.local/state \
/home/agent/.config/claude-team /home/agent/.docker/sandbox/locks \
&& chown -R agent:agent /home/agent在构建期间创建这些目录,可以让智能体在 Docker Sandboxes 挂载工作区和存储之前就成为它们的所有者。在这个示例中智能体运行时没有 sudo,所以系统软件包要在 Dockerfile 中安装。依赖单个沙箱的安装步骤请用 install 钩子。
准备证书信任
沙箱发出的 HTTPS 请求会经过代理。Docker Sandboxes 在启动时会把代理的证书颁发机构(CA)加入沙箱受信任的证书列表。UBI 把证书放在与 sbx 使用的路径不同的位置。把它们复制到预期路径,然后告诉工具使用该文件,这样它们就能同时信任公共证书和代理:
RUN update-ca-trust \
&& mkdir -p /usr/local/share/ca-certificates /etc/ssl/certs \
&& cp /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt如果你在构建期间添加了企业 CA 证书,请在运行 update-ca-trust 和复制证书包之前,把它们放到 /etc/pki/ca-trust/source/anchors/。换成其他发行版时,请使用它自己的证书管理命令和源证书包路径。
准备 shell 环境
在一个 shell 中导出的环境变量不会自动在另一个 shell 中可用。给智能体一个文件,让它可以把变量保存下来供之后的 shell 会话使用。下面的几行创建该文件,并让登录式、交互式和非交互式 Bash shell 都读取它:
RUN touch /etc/sandbox-persistent.sh \
&& chown agent:agent /etc/sandbox-persistent.sh \
&& chmod 0644 /etc/sandbox-persistent.sh \
&& printf '%s\n' '. /etc/sandbox-persistent.sh' \
> /etc/profile.d/sandbox-persistent.sh \
&& printf '%s\n' '. /etc/sandbox-persistent.sh' >> /home/agent/.bashrc
ENV HOME=/home/agent \
PATH="/home/agent/.local/bin:${PATH}" \
BASH_ENV=/etc/sandbox-persistent.shBASH_ENV 告诉非交互式 Bash 读取该文件。你会在后面的教程中为智能体加入使用它的说明。
把智能体构建进镜像
把下面内容追加到 Dockerfile,以 agent 身份安装 Claude Code 并设置它的启动命令:
USER agent
ENV CLAUDE_ENV_FILE=/etc/sandbox-persistent.sh \
IS_SANDBOX=1
ARG CLAUDE_VERSION
RUN curl -fsSL https://claude.ai/install.sh -o /tmp/install-claude.sh \
&& bash /tmp/install-claude.sh "${CLAUDE_VERSION}" \
&& rm /tmp/install-claude.sh
WORKDIR /home/agent/workspace
ENTRYPOINT ["claude", "--settings", "/home/agent/.config/claude-team/settings.json"]
CMD []以 agent 身份安装,会把 Claude Code 放在 /home/agent/ 下,该用户可以访问它。CLAUDE_ENV_FILE 把 Claude Code 指向你为持久化环境变量准备的文件。你会在下一步的描述符中设置 CLAUDE_VERSION。
Dockerfile 还设置了用户、工作目录、环境变量和启动命令。CMD [] 清除从基础镜像继承的任何参数。--settings 选项会加载你为每个沙箱选择的模型。你会在编写模型设置中创建它的设置文件。
用这个镜像创建的每个沙箱都会得到同一个 Claude Code 二进制文件。接下来的步骤配置 Docker Sandboxes 如何运行它。你添加的任何 Mixin 都必须使用 v3,并且包含与该工作负载的操作系统和架构兼容的工具。
描述工作负载及其输入
创建 claude-team/claude-team.yaml。先标识这个工作负载,并声明两个参数:
version选择在构建镜像时安装的 Claude Code 版本。model选择创建沙箱时使用的模型。
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: workload
displayName: Team Claude Code
description: Claude Code with team defaults and API-key authentication
args:
version:
default: "2.1.278"
pattern: '^[0-9]+\.[0-9]+\.[0-9]+$'
buildArg: CLAUDE_VERSION
model:
default: sonnet
enum: [sonnet, opus, haiku]
provides: ["claude@${{ kit.args.version }}"]version 设置 Dockerfile 的 CLAUDE_VERSION 构建参数。构建会用 pattern 校验该版本,然后把它写进 provides,让其他 Kit 能核对安装的是哪个 Claude Code 版本。
model 让你在创建每个沙箱时选择模型。这个选择会写进一个设置文件,因此不会改变已安装的智能体。
允许访问 API
智能体装好之后,下一步是让它能够访问 Anthropic API。在 claude-team.yaml 的顶层添加一个 capabilities 列表,放在 provides 之后:
capabilities:
- type: com.docker.sandbox/sbx@1
- type: com.docker.sandbox/network-policy@1
config:
runtime:
allow:
- api.anthropic.com:443网络规则允许在沙箱运行期间对 Anthropic API 发起 HTTPS 请求。在 Dockerfile 中下载 Claude Code 使用的是构建器的网络,因此这里不需要规则。
sbx@1 条目声明该工作负载已准备好由 sbx 管理智能体的启动。它要求的 shell 和用户账户请参阅 声明智能体启动约定。
声明凭据
Claude Code 能够访问 API,但它还需要完成身份验证。添加一项凭据能力,告诉 Docker Sandboxes 使用哪个密钥以及如何把它放进请求中。密钥会存在你的宿主机上,位于 Kit 之外。
把下面这个条目追加到同一个 capabilities 列表中:
- type: com.docker.sandbox/credential@1
description: Anthropic API access
config:
service: anthropic
phase: runtime
apiKey:
name: ANTHROPIC_API_KEY
proxyManaged: true
inject:
- domain: api.anthropic.com
header: x-api-key
format: "%s"沙箱收到的 ANTHROPIC_API_KEY 是一个占位符。当 Claude Code 向 api.anthropic.com 发起请求时,宿主代理会把真正的 API 密钥插入 x-api-key 请求头。密钥始终留在宿主机上。启动该 Kit 时,你会提供它的值并批准使用它。
编写模型设置
Dockerfile 的启动命令会读取 /home/agent/.config/claude-team/settings.json。用生命周期能力创建该文件,并写入为该沙箱选择的模型。
把下面这个条目追加到 capabilities:
- type: com.docker.sandbox/lifecycle@1
config:
files:
- path: /home/agent/.config/claude-team/settings.json
content: |
{"model": "${{ kit.args.model }}"}
mode: "0644"Docker Sandboxes 会填入选中的 model,并在 Claude Code 启动之前写入该文件。在这个时机创建文件,可以让每个沙箱用同一个镜像使用不同的模型。
Docker Sandboxes 在运行完 install 钩子之后,以 UID 1000 写入这些文件。请使用智能体可写的绝对路径,就像这个示例一样。路径中的 $HOME 之类的 shell 变量不会被展开。
添加智能体说明
该 Kit 还可以给 Claude Code 关于环境的说明。把下面的 Markdown 与描述符和 Dockerfile 放在同一目录:
## Team workflow {#team-workflow}
Read the project's README before changing code. Run the project's checks
before reporting a task complete, and report any checks you couldn't run.
Claude Code is installed in this sandbox. Its additional settings are at
`/home/agent/.config/claude-team/settings.json`.
Use `/etc/sandbox-persistent.sh` for environment exports needed by later
Bash commands. Keep shell completion scripts out of that file because
non-interactive commands also source it.把一个 agent-context 条目追加到 capabilities,即可包含这些说明:
- type: com.docker.sandbox/agent-context@1
config:
filename: CLAUDE.md
contentFile: ./context.md构建会把 context.md 包含进镜像。沙箱运行时,sbx 会在已挂载工作区的上级目录写入一个 CLAUDE.md 文件。该文件把 Claude Code 指向你的 context.md。你项目中的 CLAUDE.md 仍然留在原处。
像这个示例一样使用 contentFile,可以把较长的说明放在单独的 Markdown 文件中。你也可以用 content 代替 contentFile,直接把说明写在工作负载的描述符里。多个 Kit 的说明如何协同工作,请参阅 运行时访问和说明。
存储密钥并运行
把你的 Anthropic API 密钥存在宿主机上:
$ sbx secret set anthropic在包含 claude-team 的目录中,启动这个 Kit:
$ sbx run --name claude-team ./claude-teamsbx 会构建这个 Kit,把你当前的目录作为工作区挂载,然后启动 Claude Code。要在另一个项目上工作,把它的路径追加到命令中。在提示时,批准该 Kit 使用你存储的密钥,然后按 Claude Code 的首次运行提示操作。智能体既需要存储的密钥,也需要你批准使用它。请参阅 凭据绑定。
创建沙箱时可以选择其他模型:
$ sbx run --name claude-team-opus ./claude-team \
--kit-arg claude-team.model=opusclaude-team 前缀与本地 Kit 目录的名字一致。Docker Sandboxes 会检查 opus 属于 enum 中的选项,然后在 Claude Code 启动之前把它写入设置文件。
迭代并发布
编辑描述符、Dockerfile 或上下文文件,然后用不同的名称再创建一个沙箱来测试改动:
$ sbx run --name claude-team-test-2 ./claude-team重启已有沙箱不会应用你的改动。要在本地试用另一个智能体版本,在描述符中更新 args.version.default,然后再创建一个沙箱。
只要本地构建仍然可用,并且源文件和 Kit 参数都没有变化,sbx 就会复用它。未使用的构建可以在七天后被清理,之后再次使用时可能需要恢复或重新构建。 改动源文件或 Kit 参数都可能触发构建,即使像 model 这样只影响沙箱安装的参数也是如此。BuildKit 仍可复用未改变的镜像层。
发布工作负载
Kit 准备好分享后,登录 Docker Hub,然后用 Docker Buildx 构建并推送它。把 <NAMESPACE> 换成你可以推送的 Docker Hub 命名空间:
$ docker login
$ docker buildx build ./claude-team \
--file ./claude-team/claude-team.yaml \
--tag docker.io/<NAMESPACE>/claude-team:1.0.0 \
--push--file 选项告诉 Buildx 读取描述符。它的 syntax 行会选择 Kit 前端,由前端读取配套的 Dockerfile,并把描述符包含进发布的镜像。要发布其他版本的智能体,添加 --build-arg version=<CLAUDE_VERSION>。这个标志使用的是 Kit 参数名 version,描述符把它映射到 Dockerfile 的 CLAUDE_VERSION。
用镜像引用运行已发布的 Kit:
$ sbx run --name claude-team-shared docker.io/<NAMESPACE>/claude-team:1.0.0多平台镜像和分发细节请参阅 构建并分发 Kit。 要把一个工具与它的工作负载分开打包,请参阅 构建工具 Mixin。 该教程同样打包了 Claude Code,所以请把它的 Mixin 与 shell 工作负载一起使用。 把它与本工作负载组合,会得到两个都提供 claude 的 Kit,Docker Sandboxes 会拒绝这种组合。 你也可以把已发布的工作负载放进一个 Kit 集合,并在其中添加设置和说明。工作负载仍然负责定义如何准备基础镜像、安装智能体并启动它。