通过 Docker 容器实现安全隔离的工具运行框架。
dbox/
├── dbox.sh # 统一入口脚本
├── Dockerfile # 基础镜像
├── exec.sh # 容器入口
├── completion # 自动补全
├── install.sh # 安装脚本
│
├── <tool>/ # 工具目录
│ ├── tool.sh # 工具执行脚本(必需)
│ ├── service.sh # 服务启动脚本(服务型工具必需)
│ ├── config # 工具配置(可选)
│ ├── profiles/ # 环境配置
│ └── ...
│
├── mappings # 全局目录映射配置(可选)
├── env # 全局环境变量(可选)
└── ...
# 1. 安装(创建符号链接 ~/.local/bin/d)
./install.sh
# 2. 确保在 PATH 中
# 在 ~/.bashrc 或 ~/.zshrc 中添加
export PATH="$HOME/.local/bin:$PATH"
# 3. 启用自动补全(可选)
# 在 ~/.bashrc 或 ~/.zshrc 中添加
source /path/to/dbox/completion
# 4. 使用
d claude # 运行 claude (默认配置)
d claude-zai # 运行 claude (zai 配置)
d claude --version # 带参数运行
d codex # 运行 codex (默认配置)
d opencode # 在当前目录运行 opencode
d -s claude # 进入 claude 容器 shell(行为由 COMMAND_CONTAINER 决定)
d -u opencode # 启动 opencode serve
d -u openclaw # 启动 openclaw 服务(待实现)docs/opencode-design.md- OpenCode 工具的 command/service 混合模式设计方案opencode/README.md- OpenCode 工具的使用说明
d [flags] [tool[-profile]] [args...]| 标志 | 说明 |
|---|---|
-u, --up |
启动服务(服务型工具) |
-d, --down |
停止服务(服务型工具) |
-r, --restart |
重启服务(服务型工具) |
-l, --list |
列出运行中的服务型工具容器 |
-s, --shell |
启动容器 shell(由 COMMAND_CONTAINER 决定入口) |
-h, --help |
显示帮助 |
-v, --version |
显示版本 |
tool- 工具名称profile- 配置名称(可选,默认default),用-与工具名连接args- 传递给工具的参数
d claude # 运行 claude (默认配置)
d claude-zai # 运行 claude (zai 配置)
d claude --version # 带参数运行
d codex # 运行 codex (默认配置)
d -s claude # 进入 claude 容器 shell(行为由 COMMAND_CONTAINER 决定)
d -u openclaw # 启动 openclaw 服务(待实现)每次运行创建临时容器,执行完毕后自动删除。
必需文件:
<tool>/tool.sh- 工具执行脚本
通过 d -u <tool> 启动持久化服务容器。是否在 d <tool> [args...] 时复用该服务容器,由工具自己的 COMMAND_CONTAINER 配置决定。
必需文件:
<tool>/service.sh- 服务启动脚本<tool>/tool.sh- 工具执行脚本
容器特性:
- 容器名称:
dbox-<tool>-<profile> - 自动重启:
--restart unless-stopped - 优雅退出:30 秒
dbox 提供了 bash 和 zsh 的自动补全支持。
启用方法:
在 ~/.bashrc 或 ~/.zshrc 中添加:
source /path/to/dbox/completion使用效果:
d <Tab> # 列出所有标志和工具
d -u <Tab> # 列出所有工具
d claude-<Tab> # 列出 claude 工具的所有 profile当指定的 profile 不存在时:
- default 配置:自动从
template创建,无需确认 - 其他配置:询问是否从
template创建
容器运行时通过 volume mounts 动态构建 /sandbox/ 目录:
/sandbox/
├── entrypoint # 入口脚本(从 exec.sh 挂载)
├── tool.sh # 工具执行脚本(从工具目录挂载)
├── service.sh # 服务启动脚本(服务型工具,从工具目录挂载)
├── hooks/ # Hook 文件挂载点
│ ├── global-pre-exec
│ ├── tool-pre-exec
│ ├── profile-pre-exec
│ └── ...
└── env/ # 环境变量文件挂载点
├── global
├── tool
└── profile
<tool>/
├── tool.sh # 工具执行脚本(必需)
├── service.sh # 服务启动脚本(服务型工具必需)
├── config # 工具配置(可选)
├── pre-exec # 工具级 pre-exec hook(可选)
├── pre-exec.local # 工具级 pre-exec hook(本地,可选)
├── post-exec # 工具级 post-exec hook(可选)
├── post-exec.local # 工具级 post-exec hook(本地,可选)
├── mappings # 工具级目录映射配置
├── mappings.local # 工具级目录映射配置(本地,可选)
├── env # 工具级环境变量(可选)
├── env.local # 工具级环境变量(本地,可选)
├── data/ # 持久化数据(不提交到 git)
└── profiles/
└── template/ # 模板目录(提交到 git)
<tool>/config 文件用于设置工具特定的行为:
# 在 iTerm2 中使用 tmux -CC
TMUX_IN_ITERM=true
# d <tool> 和 d -s <tool> 时,命令落到新容器还是服务容器
COMMAND_CONTAINER=newCOMMAND_CONTAINER 可选值:
new- 启动新容器执行service- 在已运行的服务容器中执行
该配置同时影响 d <tool> 和 d -s <tool> 的行为。
默认行为:
- 工具存在
service.sh时默认service - 工具不存在
service.sh时默认new
每个 profile 优先从 template 创建;如果 template 不存在,则创建空目录:
profiles/<profile>/
├── mappings # 目录映射配置
├── mappings.local # 目录映射配置(本地,可选)
├── pre-exec # profile 级 pre-exec hook(可选)
├── pre-exec.local # profile 级 pre-exec hook(本地,可选)
├── post-exec # profile 级 post-exec hook(可选)
├── post-exec.local # profile 级 post-exec hook(本地,可选)
├── env # profile 级环境变量(可选)
├── env.local # profile 级环境变量(本地,可选)
└── ... # 其他配置文件
pre-exec(从低到高优先级):
- 全局 pre-exec
- 全局 pre-exec.local
- 工具级 pre-exec
- 工具级 pre-exec.local
- Profile 级 pre-exec
- Profile 级 pre-exec.local
- 执行命令
post-exec(倒序):
- Profile 级 post-exec.local
- Profile 级 post-exec
- 工具级 post-exec.local
- 工具级 post-exec
- 全局 post-exec.local
- 全局 post-exec
mappings 文件格式(每行一个映射):
# 注释以 # 开头
# 格式:
# f:主机路径:容器路径 (公共文件映射,不存在时创建空文件)
# d:主机路径:容器路径 (公共目录映射,不存在时自动创建目录)
# command:f:主机路径:容器路径 (仅 command 模式生效)
# command:d:主机路径:容器路径 (仅 command 模式生效)
# service:f:主机路径:容器路径 (仅 service 模式生效)
# service:d:主机路径:容器路径 (仅 service 模式生效)
# service:p:主机端口:容器端口 (仅 service 模式生效)
# 目录映射示例
d:data/.config:/home/devuser/.config
d:data/.local:/home/devuser/.local
# 单个配置文件映射
f:.claude.json:/home/devuser/.claude.json
# 相对路径相对于所属目录(全局/工具/profile)
d:.claude:/home/devuser/.claude
# 特殊变量 {cwd} 表示当前工作目录
command:d:{cwd}:{cwd}
# 仅 service 模式映射你想暴露给服务容器的目录
service:d:/Users/you/Workspace:/Users/you/Workspace
# 端口映射(仅服务型工具,仅 profile 级别生效)
# service:p:8080:8080
注意:
- 端口映射 (
p:...) 仅在 service 模式的 profile 级别 mappings 中生效,在其他级别定义会导致错误 - 端口映射必须显式写成
service:p:... command:p:...非法
# 1. 创建工具目录
mkdir -p mytool/profiles/template
# 2. 添加 tool.sh
cat > mytool/tool.sh << 'EOF'
#!/bin/bash
exec my-tool "$@"
EOF
chmod +x mytool/tool.sh
# 3. 添加 mappings(可选)
cat > mytool/mappings << 'EOF'
d:data/.config:/home/devuser/.config
EOF
# 4. 使用
d mytool# 1. 创建工具目录
mkdir -p myserver/profiles/template
# 2. 添加 tool.sh(执行命令时使用)
cat > myserver/tool.sh << 'EOF'
#!/bin/bash
exec my-server-cli "$@"
EOF
chmod +x myserver/tool.sh
# 3. 添加 service.sh(启动服务时使用)
cat > myserver/service.sh << 'EOF'
#!/bin/bash
exec my-server --port 8080
EOF
chmod +x myserver/service.sh
# 4. 添加 mappings
cat > myserver/mappings << 'EOF'
d:data:/var/lib/myserver
EOF
# 5. 使用
d -u myserver # 启动服务
d myserver status # 执行命令
d -d myserver # 停止服务项目根目录支持全局级别的配置,对所有工具生效:
mappings/mappings.local- 全局目录映射env/env.local- 全局环境变量pre-exec/pre-exec.local- 全局 pre-exec hookpost-exec/post-exec.local- 全局 post-exec hook
项目提供了 snippets.txt 文件,包含常见开发工具的安装脚本片段。
使用方法:
- 浏览
snippets.txt查找需要的工具 - 将对应的代码片段复制到适当的
pre-exec.local文件中
支持三级 env 文件,在容器启动时自动加载:
source /sandbox/env/global # 项目根目录的 env
source /sandbox/env/global.local # 项目根目录的 env.local
source /sandbox/env/tool # tool/env
source /sandbox/env/tool.local # tool/env.local
source /sandbox/env/profile # profile/env
source /sandbox/env/profile.local # profile/env.local