乐于分享
好东西不私藏

在 Docker 容器里用 OpenCLaw操控你的 Windows 浏览器

在 Docker 容器里用 OpenCLaw操控你的 Windows 浏览器

你有没有想过——坐在 WSL 的终端里,敲几行指令,就能让另一台 Windows 电脑上的 Chrome 浏览器乖乖听话?

这不是科幻。这是 OpenClaw + Chrome DevTools 技能的联袂表演。

今天我们就来完整拆解这个架构:在 WSL 的 Docker 容器中,通过 OpenClaw + Chrome DevTools 技能控制 Windows 主机上正在运行的浏览器。整个方案无需任何 VPN,也不依赖任何商业服务——纯原生实现。


先说清楚我们要做什么

想象这个场景:

你的 Windows 机器上 Chrome 浏览器正在打开着,你在正常使用。同时,你的 WSL 终端里跑着一个 Docker 容器,容器里运行着 OpenClaw(或其他 AI 编程助手)。你发出一句指令:「帮我打开百度并截图」,AI 立刻驱动 Windows 的 Chrome 完成操作——全程浏览器界面可见,操作过程透明。

这个架构的核心价值在于:

  • • 保留浏览器 GUI:你依然能看到 AI 在做什么
  • • 跨网络隔离:容器内的 AI 无法直接访问本地 9222 端口(稍后解释为什么)
  • • 原生协议:Chrome DevTools Protocol(CDP)是 Chrome 官方协议,成熟稳定

整体架构一览

第一步:Windows 端配置 Chrome 远程调试

1.1 启动 Chrome 并开启调试模式

在 Windows 命令行(CMD)中执行:

"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --remote-allow-origins=* --user-data-dir="%TEMP%\chrome-debug-profile"

参数解析

参数
含义
--remote-debugging-port=9222
在 9222 端口开启 Chrome 调试接口
--remote-debugging-address=0.0.0.0
尝试监听所有网络接口
--remote-allow-origins=*
允许任意来源访问调试接口
--user-data-dir
使用独立配置文件,避免干扰正常浏览器数据

注意:这里有一个非常重要的坑,稍后会详细说明。

1.2 ⚠️ 这个参数被 Chrome 无视了——必须用端口转发

执行上面的命令后,你运行 netstat -an | findstr 9222,会发现 Chrome 实际只监听了 127.0.0.1:9222,而不是 0.0.0.0:9222

原因:Windows 版 Chrome 出于安全考虑,在有图形界面的常规模式下,会强制将调试端口绑定到本地回环地址 127.0.0.1无论你怎么设置 --remote-debugging-address,Chrome 就是不听。

那么问题来了:WSL 容器怎么通过 127.0.0.1 访问到 Windows 上的 Chrome?

1.3 解决方案:用 netsh 做端口转发

既然 Chrome 坚持只监听本地,那么我们就用 Windows 自带的 netsh 工具,将外部请求转发给 Chrome。

以管理员身份打开 CMD,执行:

netsh interface portproxy add v4tov4 listenport=9222 listenaddress=0.0.0.0 connectport=9222 connectaddress=127.0.0.1

这条命令的含义是:将所有到达本机 0.0.0.0:9222 的请求,转发给内部的 127.0.0.1:9222,而后者恰好是 Chrome 调试端口在监听。

再次验证:

netstat -an | findstr 9222

此时你应该看到两条监听记录:

TCP    0.0.0.0:9222    0.0.0.0:0    LISTENING    ← Windows 端口代理
TCP    127.0.0.1:9222  0.0.0.0:0    LISTENING    ← Chrome 调试端口

1.4 别忘了防火墙

确保 Windows Defender 防火墙允许 9222 端口的入站连接,否则 WSL 永远连不上。

控制面板 → Windows Defender 防火墙 → 高级设置 → 入站规则 → 新建规则
→ 端口 → 9222 → 允许连接 → 完成

用完即删(不再需要远程控制时):

netsh interface portproxy delete v4tov4 listenport=9222 listenaddress=0.0.0.0

第二步:WSL 与 Docker 环境准备

确保你的 WSL 已安装并安装了 Docker。以下环境要求必须满足:

  • • WSL 2(推荐,完整 Linux 内核支持)
  • • Docker Desktop for Windows(开启 WSL 集成)或直接在 WSL 中安装 Docker
  • • Node.js 18+(用于运行 Chrome DevTools MCP)

2.1 验证 WSL 与 Docker

# 检查 WSL 版本
wsl --status

# 检查 Docker 是否可用

docker --version
docker ps

第三步:给 OpenClaw 安装 Chrome DevTools 技能

OpenClaw 使用技能(Skills)机制来扩展能力。控制 Chrome 浏览器只需安装 Chrome DevTools 技能,无需手动配置 MCP 服务器。

3.1 安装 Chrome DevTools 技能

在 OpenClaw 环境中执行:

npx skills add https://github.com/chromedevtools/chrome-devtools-mcp --skill chrome-devtools

这条命令会从 GitHub 拉取 chrome-devtools-mcp 仓库并将其注册为 OpenClaw 的 chrome-devtools 技能。安装完成后,OpenClaw 会自动识别并加载该技能,无需额外配置。

3.2 容器网络模式的关键配置

最关键的一点:必须使用 Docker 的主机网络模式(--network=host

如果你是用 Docker 方式运行 OpenClaw,确保启动命令带有 --network=host

docker run -it --rm \
  --network=host \
  openclaw/agent \
  skills add https://github.com/chromedevtools/chrome-devtools-mcp --skill chrome-devtools

为什么要用 --network=host

默认情况下,Docker 容器运行在一个独立的网络命名空间中,容器内的 localhost 只指向容器自身。--network=host 让容器直接使用宿主机的网络栈,此时 host.docker.internal 才能正确解析到 Windows 主机的 IP 地址,从而访问 Chrome 调试端口。

如果不用主机网络模式,容器内根本连不上 Windows 上的 Chrome。

注意:Chrome DevTools MCP 技能安装后,OpenClaw 会自动识别并加载,无需手动配置。开源项目地址:https://github.com/chromedevtools/chrome-devtools-mcp


第四步:验证连通性

4.1 手动测试 CDP 连接

在 WSL 终端中验证 Chrome 是否可达:

curl -s http://host.docker.internal:9222/json/version

如果返回类似以下内容,说明连接成功:

{
  "Browser"
: "Chrome/136.0.0.0",
  "Protocol-Version"
: "1.3",
  "User-Agent"
: "Mozilla/5.0 ...",
  "V8-Version"
: "13.6.0.0",
  "WebKit-Version"
: "537.36 ..."
}

4.2 使用 OpenClaw 控制浏览器

安装好 Chrome DevTools 技能后,在 OpenClaw 中直接发送指令即可:

OpenClaw 会自动调用 Chrome DevTools 技能,通过 CDP 协议控制 Windows 上的 Chrome 浏览器完成操作。


第五步:常见问题

Q1:端口转发已经配置了,但 WSL 还是连不上?

检查顺序

  1. 1. Windows 防火墙是否放行了 9222 端口?
  2. 2. netsh 端口转发是否成功?再执行一次 netstat -an | findstr 9222 确认
  3. 3. WSL 能否访问 Windows 主机?试 curl http://host.docker.internal:9222/json/version

Q2:Docker 容器内访问不到 Chrome?

核心检查:容器是否使用了 --network=host
如果不是,容器内根本访问不到 Windows 主机的端口。执行:

docker inspect <container_id> | grep -i networkmode

确认输出中包含 "NetworkMode": "host"

Q3:想保留浏览器界面,但不想每次手动启动 Chrome?

创建一个快捷方式,指向:

"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --remote-allow-origins=* --user-data-dir="%TEMP%\chrome-debug-profile"

双击快捷方式即可启动带调试模式的 Chrome。

Q4:端口转发命令报错「拒绝访问」?

必须以管理员身份运行 CMD。右键「命令提示符」→「以管理员身份运行」。


总结

整个方案的技术链路其实很清晰:

  1. 1. Chrome 在 Windows 上以调试模式启动,监听 127.0.0.1:9222
  2. 2. netsh 端口转发 将外部请求从 0.0.0.0:9222 转发给 Chrome
  3. 3. Docker 主机网络模式 让容器内可以直接访问宿主机端口
  4. 4. Chrome DevTools MCP 将 CDP 协议暴露为 AI 可调用的工具
  5. 5. OpenClaw 通过 MCP 技能驱动浏览器执行操作

核心就两句话:

Chrome 调试口被 Windows 锁在本地环回上,所以用 netsh 端口转发打穿这层隔离;Docker 容器要想访问宿主机端口,必须用主机网络模式。

搞清楚这两个「为什么」,整个方案就不难理解了。


「代码改变世界,思路决定高度。」