仅需两条命令:手把手教你在 Docker 沙箱中部署 OpenClaw 并连接本地大模型

教程2天前发布 小马良
6 0

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
仅需两条命令:手把手教你在 Docker 沙箱中部署 OpenClaw 并连接本地大模型

就是这样。您已经进入了 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 成本,并且完全私密。

© 版权声明

相关文章

暂无评论

none
暂无评论...