第 29 章 | 沙盒选择

更新于 2026/5/12
💡 进群学习加 wx: agentupdate
(申请发送: agentupdate)

第 29 章:沙盒选择

学习目标

知道何时上 Docker、何时不上、能怎么妥协——基于你项目的实际约束。

三档沙盒对比

flowchart TB
    L1["L1: git worktree + venv
(原生)"] --> L1Pros["✓ 原生速度
✓ 文件隔离
✓ 不污染全局 Python"] L1 --> L1Cons["✗ 不防意外 rm
✗ 不防恶意 curl|sh
✗ 跨机器复现差"] L2["L2: Docker bind-mount
(容器)"] --> L2Pros["✓ 进程隔离
✓ 防全局污染
✓ 跨机器复现"] L2 --> L2Cons["✗ E2E 必须出容器
✗ macOS 上慢点
✗ 配置成本"] L3["L3: Full VM
(完全隔离)"] --> L3Pros["✓ 完全隔离
✓ 安全性最高"] L3 --> L3Cons["✗ 重型
✗ macOS 桌面应用难跑"] style L1 fill:#c5e1a5 style L2 fill:#fff9c4 style L3 fill:#ffcdd2

决策树

flowchart TD
    Q1{需要 macOS GUI
(录屏/Chrome)?} Q1 -->|是| MacOS["E2E 必须 host
L3 不行"] Q1 -->|否| AnyOS["都可以"] MacOS --> Q2{安全敏感?} Q2 -->|是| Mix["L1 + L2 混合
(开发 L2, E2E host)"] Q2 -->|否| L1Pick["L1 起步即可"] AnyOS --> Q3{多人协作?} Q3 -->|是| L2Pick["L2 (复现性)"] Q3 -->|否| L1Pick style L1Pick fill:#c5e1a5 style L2Pick fill:#fff9c4 style Mix fill:#fff9c4

doc2video 的特殊约束

✗ E2E 需要 macOS avfoundation 录屏
✗ E2E 需要 Chrome 真桌面(非 headless)
✗ E2E 需要 iTerm 全屏 + tmux
  
→ 这些都不能在 Docker(Linux 容器)跑
→ 即使 Docker on Mac,avfoundation 也访问不到
→ 结论: E2E 必须在 host

所以我们 MVP 用 L1,不上 Docker。

L1 的具体配置

# Git worktree
cd ~/work/openspec
git worktree add ../doc2video-worktree -b feature/group-3

# venv
cd ../doc2video-worktree
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Claude Code 在这里跑
claude

→ 文件隔离 + Python 隔离,开销 ≈ 0。

何时该升 L2

□ 团队 ≥ 3 人
□ 跨平台开发(Linux + Mac + Windows)
□ 长期维护项目(>6 个月)
□ 真担心 agent 乱改 host

→ 命中 ≥ 2 项就上 L2。

L2 的混合模式(doc2video 适用)

flowchart TB
    Dev["开发期"] -->|developer/tester/reviewer| Container["Docker 容器内"]
    Container --> Mount["bind-mount 项目目录"]
    Container --> Pytest["pytest 在容器跑"]

    E2E["E2E 期"] -->|e2e-tester| Host["macOS host"]
    Host --> Real["真 Chrome + iTerm + ffmpeg"]
    Host --> Record["录真桌面"]

    style Container fill:#bbdefb
    style Host fill:#fff9c4

Docker 救不了什么

✗ 容器内 .env 还是被读(bind-mount 全挂了)
✗ 容器进程还能 curl 出去(除非 --network=none)
✗ 容器内 deny rm /tmp 还要 hook
✗ container escape 漏洞理论上存在

→ Docker 是"分层防御"中的一层,不是银弹

反模式

❌ "上 Docker 就安全了"
   → 还是要配 deny + hook

❌ bind-mount 整个 home 目录
   → 等于没沙盒

❌ E2E 跑在容器
   → macOS GUI 项目失败

❌ MVP 阶段就上 L3(VM)
   → 工程量过大,收益微弱

❌ L1 但完全不限 permission
   → 等价于裸奔

你现在能做什么

  • 给自己项目选合适的沙盒级别
  • 知道 Docker 解决什么、解决不了什么
  • 设计混合模式(开发 L2 + E2E host)