我使用UNRAID部署OpenClaw有一段时间了,它作为一个智能助手确实好用。但最近遇到一个问题:OpenClaw的浏览器自动化功能需要Chromium,而Docker容器内没有浏览器,直接安装又会有各种兼容性问题。
经过一番折腾,我找到了一个更优雅的解决方案——使用独立的browserless容器作为外部浏览器服务,让OpenClaw远程连接使用。这篇文章记录整个过程,希望能帮到有类似需求的人。
为什么选browserless
最初我尝试过几种方案:
容器内安装Chromium:可以装,但启动困难,还需要处理用户数据目录等问题
使用主机浏览器:需要配置MCP连接,Docker容器环境复杂
独立浏览器容器:最终选择了这个方案
browserless/chromium有几个优势:
专为自动化设计,提供了WebSocket接口
完整的CDP(Chrome DevTools Protocol)支持
资源控制(并发限制、超时控制等)
带认证token的访问控制
镜像用的是ghcr.io/browserless/chromium,UNRAID社区应用商店有现成的模板。
在UNRAID上部署browserless
UNRAID的Docker GUI让部署变得直观。我用的模板生成命令如下:
docker run \
-d \
--name='browserless' \
--net='bridge' \
--pids-limit 2048 \
-e TZ="Asia/Shanghai" \
-e HOST_OS="Unraid" \
-e HOST_HOSTNAME="Tower" \
-e HOST_CONTAINERNAME="browserless" \
-e 'SCREEN_WIDTH'='2560' \
-e 'SCREEN_HEIGHT'='1440' \
-e 'SCREEN_DEPTH'='16' \
-e 'TIMEOUT'='300000' \
-e 'ENABLE_DEBUGGER'='true' \
-e 'CONCURRENT'='5' \
-e 'QUEUED'='10' \
-e 'TOKEN'='你的认证令牌' \
-e 'DOWNLOAD_DIR'='/downloads' \
-e 'DATA_DIR'='/user_data' \
-l net.unraid.docker.managed=dockerman \
-l net.unraid.docker.icon='https://raw.githubusercontent.com/masterwishx/unraid-templates/main/images/browserless_logo.png' \
-p '6999:3000/tcp' \
-v '/mnt/disk1/appdata/browserless/user_data/':'/user_data':'rw' \
-v '/mnt/user/appdata/browserless/downloads/':'/downloads':'rw' \
--restart=unless-stopped \
--shm-size=2G \
'ghcr.io/browserless/chromium'
几点说明:
端口映射:容器内3000映射到主机6999,选这个端口是为了不和现有服务冲突
并发控制:CONCURRENT=5 最多5个并发会话,家庭使用足够
超时设置:TIMEOUT=300000 单个会话最长5分钟
虚拟显示:SCREEN_WIDTH/HEIGHT/DEPTH 确保有“屏幕”可用
存储策略:用户数据放机械硬盘阵列,下载目录放缓存池
共享内存:--shm-size=2G Chromium需要足够共享内存
认证token:TOKEN 环境变量设置访问令牌
部署后遇到一个权限问题:WebSocket连接返回500错误。查看日志发现是/user_data目录权限问题,容器内用户无权写入。解决方法是在UNRAID的终端里:
# 进入容器
docker exec -it browserless bash
# 修复权限
chown -R 1000:1000 /user_data
服务启动后,验证几个关键端点:
# 健康检查
curl "http://你的服务器IP:6999/pressure?token=你的令牌"
# 返回:{"pressure": {"isAvailable": true, ...}}
# CDP信息
curl "http://你的服务器IP:6999/json/version?token=你的令牌"
# 返回浏览器版本和WebSocket地址
OpenClaw集成配置
这是最折腾的部分。OpenClaw的browser工具配置有几个坑。
初始配置尝试
一开始我直接配了WebSocket地址:
{
"browser": {
"defaultProfile": "browserless",
"profiles": {
"browserless": {
"wsEndpoint": "ws://服务器IP:6999/chromium?token=xxx",
"headless": true,
"defaultViewport": {"width": 1280, "height": 720}
}
}
}
}
结果OpenClaw的配置验证直接报错:Unrecognized keys: "wsEndpoint", "headless", "defaultViewport"。
查了OpenClaw的配置文档才发现,字段名不对。
正确配置结构
正确的配置应该是:
{
"browser": {
"defaultProfile": "browserless",
"profiles": {
"browserless": {
"cdpUrl": "ws://服务器IP:6999/chromium?token=你的令牌",
"color": "#4A90E2",
"attachOnly": true
}
}
}
}
关键点:
用cdpUrl而不是wsEndpoint
attachOnly: true表示这是远程CDP连接
color只是界面显示用的颜色标识
但这个配置还是不工作,OpenClaw报错:Remote CDP for profile "browserless" is not reachable。
私有网络访问限制
折腾了很久才发现问题根源:OpenClaw默认禁止访问私有IP地址(192.168.x.x)。这是安全策略,防止SSRF攻击。
解决方案是添加ssrfPolicy配置:
{
"browser": {
"defaultProfile": "browserless",
"ssrfPolicy": {
"dangerouslyAllowPrivateNetwork": true
},
"profiles": {
"browserless": {
"cdpUrl": "ws://服务器IP:6999/chromium?token=你的令牌",
"color": "#4A90E2",
"attachOnly": true
}
}
}
}
dangerouslyAllowPrivateNetwork: true这个名字很直白——允许访问私有网络确实有风险,但在家庭内网环境下可以接受。
为什么不使用HTTP发现端点
你可能会问:为什么不用http://服务器IP:6999/json/version作为cdpUrl,让OpenClaw自动发现WebSocket地址?
我试过,不行。因为browserless返回的webSocketDebuggerUrl是ws://0.0.0.0:3000/——容器内部地址,外部无法访问。所以必须直接指定WebSocket地址。
验证配置
配置完成后,重启OpenClaw网关,然后验证:
# 检查状态
openclaw browser status
# 应该看到:running: true, cdpReady: true
# 测试连接
openclaw browser --browser-profile browserless open https://example.com
# 返回页面信息表示成功
我用我的博客做测试:
openclaw browser --browser-profile browserless open https://c3c3c3.xyz
# 返回:{"targetId": "...", "title": "c3c3c3的代码世界", "url": "https://c3c3c3.xyz/"}
还可以进一步测试页面截图、元素查找等功能,确认浏览器自动化完全可用。
核心经验总结
私有网络限制是最大障碍:OpenClaw默认安全策略会阻止访问内网IP,需要显式允许。
配置字段名要准确:OpenClaw有严格的配置验证,字段名必须和文档一致。
地址选择很重要:browserless的HTTP发现端点返回内部地址,应该直接使用WebSocket地址。
Docker权限问题:数据目录挂载要注意容器内用户的写入权限。
配置修改流程:修改前备份、验证JSON语法、用户手动重启——特别是生产环境。
完整配置参考
这是最终生效的配置,放在~/.openclaw/openclaw.json的browser字段:
{
"browser": {
"defaultProfile": "browserless",
"ssrfPolicy": {
"dangerouslyAllowPrivateNetwork": true
},
"profiles": {
"browserless": {
"cdpUrl": "ws://服务器IP:6999/chromium?token=你的令牌",
"color": "#4A90E2",
"attachOnly": true
}
}
}
}
对应的browserless Docker运行命令就是前面提到的UNRAID模板生成的那个完整命令。
替代方案考虑
如果你不想用browserless,还有其他选项:
Selenium/Standalone-Chrome:更传统的方案,但配置稍复杂
Playwright容器:如果只需要Chromium,也可以考虑
Chrome Headless直接运行:在宿主机运行,Docker容器通过端口连接
但browserless对我来说最合适:专门为自动化设计,有并发控制,带WebSocket接口,社区活跃。
最后的话
这次配置过程花了些时间,主要是OpenClaw的私有网络限制没有在错误信息里明确提示。但解决方案一旦找到,其实很简洁。
现在我的OpenClaw有了完整的外部浏览器自动化能力,而且浏览器服务是独立的,可以单独管理、监控、重启。资源消耗也更可控——browserless容器只有需要时才启动浏览器进程。
如果你是UNRAID用户,也在用OpenClaw或其他需要浏览器自动化的工具,这个方案值得一试。关键是记住那三个配置:ssrfPolicy、cdpUrl、attachOnly。
配置成功后,你会得到一个稳定、可维护的外部浏览器自动化服务,既解决了OpenClaw容器内无浏览器的问题,又避免了单一容器的复杂性。这种微服务化的思路,在UNRAID这样的家庭服务器环境里特别实用。