docker-sandbox

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker Sandbox for Agent Tools

面向Agent工具的Docker沙箱

Isolated execution of
claude
,
codex
, and other agent tools using Docker Desktop's
docker sandbox
(v0.11.0+). Uses existing Claude Max and ChatGPT Pro subscriptions — no API key billing.
使用Docker Desktop的
docker sandbox
(v0.11.0及以上版本)实现
claude
codex
和其他Agent工具的隔离执行。可使用现有的Claude Max和ChatGPT Pro订阅,无需额外支付API密钥费用。

Prerequisites

前置要求

  • Docker Desktop running (OrbStack works)
  • docker sandbox version
    returns ≥0.11.0
  • Auth secrets stored in
    agent-secrets
    :
    • claude_setup_token
      — from
      claude setup-token
      (1-year token, Max subscription)
    • codex_auth_json
      — contents of
      ~/.codex/auth.json
      (ChatGPT Pro subscription)
  • Docker Desktop处于运行状态(OrbStack也可)
  • docker sandbox version
    返回版本≥0.11.0
  • 身份验证密钥存储在
    agent-secrets
    中:
    • claude_setup_token
      — 来自
      claude setup-token
      (有效期1年的令牌,需Max订阅)
    • codex_auth_json
      ~/.codex/auth.json
      的文件内容(需ChatGPT Pro订阅)

Quick Reference

快速参考

bash
undefined
bash
undefined

Create a sandbox

创建一个沙箱

docker sandbox create --name my-sandbox claude /path/to/project
docker sandbox create --name my-sandbox claude /path/to/project

Run a command in it

在沙箱中运行命令

docker sandbox exec -e "CLAUDE_CODE_OAUTH_TOKEN=..." -w /path/to/project my-sandbox
claude -p "implement the feature" --output-format text --dangerously-skip-permissions
docker sandbox exec -e "CLAUDE_CODE_OAUTH_TOKEN=..." -w /path/to/project my-sandbox
claude -p "implement the feature" --output-format text --dangerously-skip-permissions

List sandboxes

列出所有沙箱

docker sandbox ls
docker sandbox ls

Remove

删除沙箱

docker sandbox rm my-sandbox
undefined
docker sandbox rm my-sandbox
undefined

Auth Setup (One-Time)

身份验证配置(仅需一次)

Claude (Max subscription)

Claude(需Max订阅)

Run interactively on the host (needs browser for OAuth):
bash
claude setup-token
This opens a browser, completes OAuth, and prints a token like
sk-ant-oat01-...
. Valid for 1 year.
Store it:
bash
secrets add claude_setup_token --value "sk-ant-oat01-..."
Use in sandbox:
bash
TOKEN=$(secrets lease claude_setup_token --ttl 1h --raw)
docker sandbox exec -e "CLAUDE_CODE_OAUTH_TOKEN=$TOKEN" my-sandbox claude auth status
在主机上交互式运行(需要浏览器完成OAuth):
bash
claude setup-token
该命令会打开浏览器完成OAuth验证,并输出格式为
sk-ant-oat01-...
的令牌,有效期为1年
存储令牌:
bash
secrets add claude_setup_token --value "sk-ant-oat01-..."
在沙箱中使用:
bash
TOKEN=$(secrets lease claude_setup_token --ttl 1h --raw)
docker sandbox exec -e "CLAUDE_CODE_OAUTH_TOKEN=$TOKEN" my-sandbox claude auth status

→ loggedIn: true, authMethod: oauth_token

→ loggedIn: true, authMethod: oauth_token

undefined
undefined

Codex (ChatGPT Pro subscription)

Codex(需ChatGPT Pro订阅)

Authenticate codex locally (needs browser):
bash
codex  # Select "Sign in with ChatGPT", complete OAuth
The auth file at
~/.codex/auth.json
is portable (not host-tied). Store it:
bash
secrets add codex_auth_json --value "$(cat ~/.codex/auth.json)"
Inject into sandbox:
bash
AUTH=$(secrets lease codex_auth_json --ttl 1h --raw)
docker sandbox exec my-sandbox bash -c "mkdir -p ~/.codex && cat > ~/.codex/auth.json << 'EOF'
${AUTH}
EOF"
在本地完成codex身份验证(需要浏览器):
bash
codex  # 选择"Sign in with ChatGPT",完成OAuth验证
位于
~/.codex/auth.json
的验证文件是可移植的(不绑定主机),存储该文件:
bash
secrets add codex_auth_json --value "$(cat ~/.codex/auth.json)"
注入到沙箱中:
bash
AUTH=$(secrets lease codex_auth_json --ttl 1h --raw)
docker sandbox exec my-sandbox bash -c "mkdir -p ~/.codex && cat > ~/.codex/auth.json << 'EOF'
${AUTH}
EOF"

Token Refresh

令牌刷新

TokenLifetimeRefresh
claude_setup_token
1 yearRun
claude setup-token
again, update secret
codex_auth_json
Until subscription changeRe-run
codex
login if auth fails, update secret
令牌有效期刷新方式
claude_setup_token
1年重新运行
claude setup-token
,更新密钥
codex_auth_json
到订阅变更为止如果验证失败则重新运行
codex
登录,更新密钥

Agent Loop Integration

Agent循环集成

Pre-warm Pattern

预热模式

Create sandbox(es) at loop start, reuse for all stories, destroy at loop end.
PLANNER (loop start)
  ├── docker sandbox create --name loop-{loopId}-claude claude {workDir}
  ├── docker sandbox create --name loop-{loopId}-codex codex {workDir}  # if needed
  └── inject auth into both

IMPLEMENTOR / TEST-WRITER / REVIEWER (per story)
  └── docker sandbox exec -w {workDir} -e CLAUDE_CODE_OAUTH_TOKEN=... loop-{loopId}-{tool} \
        {tool command}
      # ~90ms overhead, workspace changes visible on host immediately

COMPLETE / CANCEL (loop end)
  ├── docker sandbox rm loop-{loopId}-claude
  └── docker sandbox rm loop-{loopId}-codex
在循环启动时创建沙箱,所有任务复用沙箱,循环结束时销毁沙箱。
PLANNER (循环启动)
  ├── docker sandbox create --name loop-{loopId}-claude claude {workDir}
  ├── docker sandbox create --name loop-{loopId}-codex codex {workDir}  # 按需创建
  └── 向两个沙箱注入验证信息

IMPLEMENTOR / TEST-WRITER / REVIEWER (每个任务)
  └── docker sandbox exec -w {workDir} -e CLAUDE_CODE_OAUTH_TOKEN=... loop-{loopId}-{tool} \
        {tool command}
      # ~90ms开销,工作区变更会立即同步到主机

COMPLETE / CANCEL (循环结束)
  ├── docker sandbox rm loop-{loopId}-claude
  └── docker sandbox rm loop-{loopId}-codex

Timing

耗时说明

OperationTime
Create (cached image)~14s
Exec (warm sandbox)~90ms
Stop~11s
Remove~150ms
Net overhead per loop: ~14s create + ~90ms × N stories = negligible for loops running 5-10 stories at 5-15min each.
操作耗时
创建(使用缓存镜像)~14s
执行(预热后的沙箱)~90ms
停止~11s
删除~150ms
每个循环的总开销:~14s创建时间 + ~90ms × 任务数,对于单次运行5-10个任务、总时长5-15分钟的循环来说开销可忽略。

Workspace Mount

工作区挂载

The workspace is bidirectional — same path on host and in sandbox:
  • File created in sandbox → visible on host at same path
  • File created on host → visible in sandbox
  • Git operations work normally (host sees sandbox changes, sandbox sees host commits)
工作区是双向同步的,主机和沙箱中的路径一致:
  • 沙箱中创建的文件 → 主机同路径下可见
  • 主机中创建的文件 → 沙箱中可见
  • Git操作可正常运行(主机可见沙箱的变更,沙箱可见主机的提交)

Sandbox Templates

沙箱模板

TemplateTools Included
claude
claude 2.1.42, git, node 20, npm
codex
codex 0.101.0, git, node 20, npm
Neither includes
bun
. If bun is needed, use host-mode fallback or install it post-create.
模板内置工具
claude
claude 2.1.42, git, node 20, npm
codex
codex 0.101.0, git, node 20, npm
两个模板都不包含
bun
,如果需要使用bun,可以降级到主机模式或者在沙箱创建后手动安装。

Env Vars

环境变量

Pass via
docker sandbox exec -e
:
bash
docker sandbox exec \
  -e "CLAUDE_CODE_OAUTH_TOKEN=$TOKEN" \
  -e "NODE_ENV=development" \
  -w /path/to/project \
  my-sandbox \
  claude -p "prompt" --output-format text --dangerously-skip-permissions
通过
docker sandbox exec -e
传入:
bash
docker sandbox exec \
  -e "CLAUDE_CODE_OAUTH_TOKEN=$TOKEN" \
  -e "NODE_ENV=development" \
  -w /path/to/project \
  my-sandbox \
  claude -p "prompt" --output-format text --dangerously-skip-permissions

Network Control

网络控制

Sandboxes have network access by default. Restrict with proxy rules:
bash
undefined
沙箱默认开放网络访问,可通过代理规则限制访问:
bash
undefined

Allow only API endpoints

仅允许访问API端点

docker sandbox network proxy my-sandbox --policy deny docker sandbox network proxy my-sandbox --allow-host api.anthropic.com docker sandbox network proxy my-sandbox --allow-host api.openai.com
undefined
docker sandbox network proxy my-sandbox --policy deny docker sandbox network proxy my-sandbox --allow-host api.anthropic.com docker sandbox network proxy my-sandbox --allow-host api.openai.com
undefined

Fallback to Host Mode

降级到主机模式

If Docker is unavailable:
bash
undefined
如果Docker不可用:
bash
undefined

Check availability

检查可用性

docker info >/dev/null 2>&1 || echo "Docker not available"
docker info >/dev/null 2>&1 || echo "Docker not available"

Force host mode

强制启用主机模式

export AGENT_LOOP_HOST=1
undefined
export AGENT_LOOP_HOST=1
undefined

Saving Custom Templates

保存自定义模板

If you install additional tools in a sandbox, save it as a template:
bash
undefined
如果你在沙箱中安装了额外工具,可以将其保存为模板:
bash
undefined

Install tools

安装工具

docker sandbox exec my-sandbox bash -c 'npm i -g @anthropic-ai/claude-code @openai/codex'
docker sandbox exec my-sandbox bash -c 'npm i -g @anthropic-ai/claude-code @openai/codex'

Save as template

保存为模板

docker sandbox save my-sandbox my-agent-template:v1
docker sandbox save my-sandbox my-agent-template:v1

Use the template for future sandboxes

后续创建沙箱时使用该模板

docker sandbox create --name fast-sandbox -t my-agent-template:v1 claude /path/to/project
undefined
docker sandbox create --name fast-sandbox -t my-agent-template:v1 claude /path/to/project
undefined

Implementation in utils.ts

在utils.ts中实现

New Functions (ADR-0023)

新增函数(ADR-0023)

typescript
// Create sandbox for a loop
async function createLoopSandbox(
  loopId: string,
  tool: "claude" | "codex",
  workDir: string
): Promise<string>  // returns sandbox name

// Execute command in existing sandbox
async function execInSandbox(
  sandboxName: string,
  command: string[],
  opts: { env?: Record<string, string>; workDir?: string; timeout?: number }
): Promise<{ exitCode: number; output: string }>

// Destroy loop sandbox(es)
async function destroyLoopSandbox(loopId: string): Promise<void>
typescript
// 为循环创建沙箱
async function createLoopSandbox(
  loopId: string,
  tool: "claude" | "codex",
  workDir: string
): Promise<string>  // 返回沙箱名称

// 在现有沙箱中执行命令
async function execInSandbox(
  sandboxName: string,
  command: string[],
  opts: { env?: Record<string, string>; workDir?: string; timeout?: number }
): Promise<{ exitCode: number; output: string }>

// 销毁循环关联的沙箱
async function destroyLoopSandbox(loopId: string): Promise<void>

Replacing spawnTool()

替换spawnTool()

Current
spawnTool()
in implement.ts checks
AGENT_LOOP_HOST
and
isDockerAvailable()
. Update it to:
  1. Check if sandbox
    loop-{loopId}-{tool}
    exists (created by planner)
  2. If yes →
    execInSandbox()
    with auth env vars
  3. If no → fall back to
    spawnToolHost()
    (current host-mode behavior)
当前implement.ts中的
spawnTool()
会检查
AGENT_LOOP_HOST
isDockerAvailable()
,将其更新为如下逻辑:
  1. 检查是否存在
    loop-{loopId}-{tool}
    沙箱(由规划器创建)
  2. 如果存在 → 传入验证环境变量调用
    execInSandbox()
  3. 如果不存在 → 降级到
    spawnToolHost()
    (当前的主机模式逻辑)

Troubleshooting

问题排查

"Not logged in" in sandbox

沙箱中提示“未登录”

Auth not injected. Check:
bash
docker sandbox exec my-sandbox bash -c 'claude auth status'
docker sandbox exec my-sandbox bash -c 'cat ~/.codex/auth.json | head -3'
验证信息未注入,检查:
bash
docker sandbox exec my-sandbox bash -c 'claude auth status'
docker sandbox exec my-sandbox bash -c 'cat ~/.codex/auth.json | head -3'

Sandbox creation slow

沙箱创建缓慢

First pull downloads ~500MB image. Subsequent creates use cached image (~14s). Use
docker sandbox save
to create a pre-configured template.
首次拉取需要下载约500MB的镜像,后续创建会使用缓存镜像(约14s)。可使用
docker sandbox save
创建预配置的模板加快速度。

File not visible between host and sandbox

主机和沙箱之间文件不可见

Only the workspace path is mounted. Files outside the workspace directory are not shared.
只有工作区路径会被挂载,工作区目录外的文件不会共享。

"docker sandbox: command not found"

提示“docker sandbox: command not found”

Docker Desktop must be running. Check version:
docker sandbox version
. Requires Docker Desktop 4.40+ with sandbox extension.
必须运行Docker Desktop,检查版本:
docker sandbox version
。需要安装了沙箱扩展的Docker Desktop 4.40及以上版本。