Docker Sandboxes 是 Docker 生态系统中的一种新原语,它允许您在隔离的微型虚拟机中运行 AI 代理或任何其他工作负载。它提供了强大的隔离性、便捷的开发者体验,并通过可配置的网络代理来拒绝代理连接到任意互联网主机,从而构建了一个强大的安全边界。网络代理还将方便地注入 API 密钥,例如您的 ANTHROPIC_API_KEY 或 OPENAI_API_KEY,使得代理根本无法访问它们,也无法泄露它们。
在之前的一篇文章中,我展示了 Docker Sandboxes 如何让您将 AI 代理可能需要的任何工具(例如用于 Java 项目的 JDK 或一些自定义 CLI)安装到一个与主机隔离的容器中。今天,我们将更进一步:我们将通过 Docker Model Runner,在本地模型上运行 OpenClaw——一个开源的 AI 编码代理。
无需 API 密钥,无需云成本,完全私密。而且您只需大约 2 条命令即可完成。
快速开始
确保您已安装 Docker Desktop,并且已启用 Docker Model Runner(设置 → Docker Model Runner → 启用),然后拉取一个模型:
docker model pull ai/gpt-oss:20B-UD-Q4_K_XL
现在创建并运行沙箱:
docker sandbox create --name openclaw -t olegselajev241/openclaw-dmr:latest shell .
docker sandbox network proxy openclaw --allow-host localhost
docker sandbox run openclaw
在沙箱内部:
~/start-openclaw.sh

就是这样。您已经进入了 OpenClaw 的终端 UI,并与您机器上的本地 gpt-oss 模型进行交互。该模型在您主机上的 Docker Model Runner 中运行,而 OpenClaw 则完全隔离在沙箱中运行:它只能读取和写入您赋予它的工作区中的文件,并且有一个网络代理可以拒绝连接到不需要的主机。
云模型同样适用
沙箱代理会自动从您的主机环境中注入 API 密钥。如果您设置了 ANTHROPIC_API_KEY 或 OPENAI_API_KEY,OpenClaw 可以运行云模型,只需在 OpenClaw 设置中指定它们即可。代理负责凭证注入,因此您的密钥永远不会暴露在沙箱内部。
这意味着您可以使用免费的本地模型进行实验,然后在同一个沙箱中切换到云模型进行严肃的工作。使用云模型时,您甚至不需要允许代理访问主机的 localhost,因此无需运行 docker sandbox network proxy openclaw --allow-host localhost。
选择您的模型
启动脚本会自动发现 Docker Model Runner 中可用的模型。列出它们:
~/start-openclaw.sh list
使用特定模型:
~/start-openclaw.sh ai/qwen2.5:7B-Q4_K_M
您用 docker model pull 拉取的任何模型都可用。
工作原理(技术细节)
预构建的镜像 (olegselajev241/openclaw-dmr:latest) 基于 shell 沙箱模板,并增加了三个部分:Node.js 22、OpenClaw 和一个微型网络桥接器。
需要这个桥接器是因为 Docker Model Runner 运行在您的主机上并绑定到 localhost:12434。但沙箱内部的 localhost 指的是沙箱本身,而不是您的主机。沙箱确实有一个 HTTP 代理,位于 host.docker.internal:3128,可以访问主机服务,并且我们通过 docker sandbox network proxy --allow-host localhost 允许它访问 localhost。
问题在于 OpenClaw 是基于 Node.js 的,而 Node.js 不尊重 HTTP_PROXY 环境变量。因此,我们编写了一个大约 20 行的桥接脚本,OpenClaw 连接到该脚本的 127.0.0.1:54321,该脚本显式地通过代理转发请求,以到达主机上的 Docker Model Runner:
OpenClaw → 桥接器 (localhost:54321) → 代理 (host.docker.internal:3128) → Model Runner (主机 localhost:12434)
start-openclaw.sh 脚本会启动桥接器,启动 OpenClaw 的网关(清除代理变量以便它直接连接桥接器),然后运行 TUI。
构建您自己的镜像
想要自定义镜像或只是想看看它是如何工作的?以下是完整的构建过程。
1. 创建一个基础沙箱并安装 OpenClaw
docker sandbox create --name my-openclaw shell .
docker sandbox network proxy my-openclaw --allow-host localhost
docker sandbox run my-openclaw
现在,在沙箱中安装 OpenClaw:
# 安装 Node 22(OpenClaw 需要它)
npm install -g n && n 22
hash -r
# 安装 OpenClaw
npm install -g openclaw@latest
# 运行初始设置
openclaw setup
2. 创建 Model Runner 桥接器
这是关键部分——一个微小的 Node.js 服务器,通过沙箱代理将请求转发到您主机上的 Docker Model Runner:
cat > ~/model-runner-bridge.js << 'EOF'
const http = require("http");
const { URL } = require("url");
const PROXY = new URL(process.env.HTTP_PROXY || "http://host.docker.internal:3128");
const TARGET = "localhost:12434";
http.createServer((req, res) => {
const proxyReq = http.request({
hostname: PROXY.hostname,
port: PROXY.port,
path: "http://" + TARGET + req.url,
method: req.method,
headers: { ...req.headers, host: TARGET }
}, proxyRes => {
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res);
});
proxyReq.on("error", e => { res.writeHead(502); res.end(e.message); });
req.pipe(proxyReq);
}).listen(54321, "127.0.0.1");
EOF
3. 配置 OpenClaw 以使用 Docker Model Runner
现在将 Docker Model Runner 提供商合并到 OpenClaw 的配置中:
python3 -c "
import json
import os
p = os.path.expanduser('~/.openclaw/openclaw.json')
with open(p) as f: cfg = json.load(f)
cfg['models'] = cfg.get('models', {})
cfg['models']['mode'] = 'merge'
cfg['models']['providers'] = cfg['models'].get('providers', {})
cfg['models']['providers']['docker-model-runner'] = {
'baseUrl': 'http://127.0.0.1:54321/engines/llama.cpp/v1',
'apiKey': 'not-needed',
'api': 'openai-completions',
'models': [{
'id': 'ai/qwen2.5:7B-Q4_K_M',
'name': 'Qwen 2.5 7B (Docker Model Runner)',
'reasoning': False, 'input': ['text'],
'cost': {'input': 0, 'output': 0, 'cacheRead': 0, 'cacheWrite': 0},
'contextWindow': 32768, 'maxTokens': 8192
}]
}
cfg['agents'] = cfg.get('agents', {})
cfg['agents']['defaults'] = cfg['agents'].get('defaults', {})
cfg['agents']['defaults']['model'] = {'primary': 'docker-model-runner/ai/qwen2.5:7B-Q4_K_M'}
cfg['gateway'] = {'mode': 'local'}
with open(p, 'w') as f: json.dump(cfg, f, indent=2)
"
4. 保存并分享
退出沙箱并将其保存为可重用的镜像:
docker sandbox save my-openclaw my-openclaw-image:latest
将其推送到仓库,以便任何人都可以使用它:
docker tag my-openclaw-image:latest yourname/my-openclaw:latest
docker push yourname/my-openclaw:latest
任何拥有 Docker Desktop(包含现代沙箱功能)的人都可以通过以下命令启动相同的环境:
docker sandbox create --name openclaw -t yourname/my-openclaw:latest shell .
下一步
Docker Sandboxes 使得在隔离、可重现的环境中运行任何 AI 编码代理变得容易。结合 Docker Model Runner,您可以获得一个完全本地的 AI 编码设置:没有云依赖,没有 API 成本,并且完全私密。















