- IDENTITY.md §四: 新增主动思考+主动研究要求 - SOUL.md §一: 新增第4条(主动优于被动)+第5条(自研胜过求助) - SOUL.md §六: 升级为3级决策框架 - HEARTBEAT.md: 新增主动触发场景表 - TOOLS.md §2.1/4.2: 补充运维脚本+搜索研究规则 - insights.md: 追加工作姿态升级反思 - knowledge/research-log.md: 新建研究沉淀文档
42 KiB
OpenClaw 群晖 NAS DS925+ 运维手册
最后更新:2026-04-21
维护者:Tyrone
设备:群晖 DS925+ (OrpaonNAS)
1. 系统环境
| 项目 | 值 |
|---|---|
| NAS 型号 | Synology DS925+ |
| NAS 主机名 | OrpaonNAS |
| NAS 局域网 IP | 192.168.0.130 |
| DSM 版本 | 7.x |
| Docker | Container Manager |
| SSH 用户 | Tyrone (UID=1026, GID=100) |
2. OpenClaw 部署信息
2.1 容器配置
| 项目 | 值 |
|---|---|
| 容器名 | openclaw |
| 镜像 | docker.1ms.run/alpine/openclaw:latest |
| 镜像代理 | docker.1ms.run(国内加速) |
| 运行用户 | node (UID=1026, GID=100) |
| 重启策略 | always |
| 端口映射 | 0.0.0.0:18789->18789/tcp |
| 当前版本 | v2026.4.12 |
| 最新版本 | v2026.4.14 |
2.2 创建容器命令
# 1) 创建专用 Docker 网络(openclaw 与 browserless 通信必须在同一网络)
docker network create openclaw-net 2>/dev/null || true
# 2) 创建 openclaw 容器(连入 openclaw-net)
docker run -d \
--name openclaw \
--restart always \
--network openclaw-net \
-p 18789:18789 \
-v /volume1/docker/openclaw-data:/home/node/.openclaw \
-e PUID=1026 \
-e PGID=100 \
docker.1ms.run/alpine/openclaw:latest
⚠️ 注意:Volume 必须映射到
/home/node/.openclaw(node 用户 home 目录),不要映射到/root/.openclaw。
2.3 Browserless Sidecar 容器(浏览器能力依赖)
OpenClaw 浏览器能力通过 Remote CDP 连接外置 browserless 容器实现;必须与 openclaw 同处 openclaw-net,且不启用 TOKEN(原因见第 12 章)。
# 创建持久化目录(首次)
sudo mkdir -p /volume1/docker/browserless-profile
sudo chown -R 1000:1000 /volume1/docker/browserless-profile
sudo chmod -R 777 /volume1/docker/browserless-profile # 群晖必须,否则 Chrome 报 Permission denied
# 清除残留锁文件(如有)
sudo rm -f /volume1/docker/browserless-profile/SingletonLock
docker run -d \
--name browserless \
--restart always \
--network openclaw-net \
-v /volume1/docker/browserless-profile:/profile \
-e MAX_CONCURRENT_SESSIONS=10 \
-e KEEP_ALIVE=true \
-e CONNECTION_TIMEOUT=600000 \
-e DEFAULT_USER_DATA_DIR=/profile \
-e DEFAULT_STEALTH=true \
browserless/chrome:latest
参数说明:
| 环境变量 | 值 | 作用 |
|---|---|---|
MAX_CONCURRENT_SESSIONS |
10 | 避免 OpenClaw 重连时被排队 |
KEEP_ALIVE |
true | 空闲时不立即销毁,稳定连续请求 |
CONNECTION_TIMEOUT |
600000 | 10 分钟空闲超时 |
DEFAULT_USER_DATA_DIR |
/profile | Chrome 用户数据持久化(Cookie/登录态跨重启保留) |
DEFAULT_STEALTH |
true | 反检测模式(降低被网站识别为自动化的概率) |
⚠️ 不使用
PREBOOT_CHROME/PREBOOT_QUANTITY:预热会启动多个 Chrome 实例,与DEFAULT_USER_DATA_DIR共享同一 profile 目录时触发SingletonLock互斥锁冲突,导致 Chrome 启动失败。KEEP_ALIVE=true已能保证会话间复用,无需预热。
⚠️ 禁止设置
TOKEN环境变量。OpenClaw 在可达性探测阶段会请求/json/version但不带 token,启用 TOKEN 会导致 403 → 被误判为Remote CDP not reachable。改由 Docker 网络隔离保障安全。
⚠️ 群晖权限问题:创建容器前必须先
sudo chmod -R 777 /volume1/docker/browserless-profile,否则群晖挂载卷默认只读权限导致 Chrome 报Permission denied无法启动。容器重启后若报SingletonLock: File exists,执行sudo rm -rf /volume1/docker/browserless-profile/SingletonLock /volume1/docker/browserless-profile/SingletonCookie /volume1/docker/browserless-profile/SingletonSocket清除残留锁文件。
3. 路径映射
3.1 持久化数据
| NAS 宿主机路径 | 容器内路径 | 用途 |
|---|---|---|
/volume1/docker/openclaw-data/ |
/home/node/.openclaw/ |
配置、数据、workspace |
3.2 已废弃路径
| NAS 宿主机路径 | 说明 |
|---|---|
/volume1/docker/openclaw/ |
旧映射(/root/.openclaw),已废弃,可删除 |
3.3 应用程序文件(随镜像更新,不持久化)
| 容器内路径 | 用途 |
|---|---|
/app/dist/ |
编译后的 OpenClaw 核心程序 |
/app/skills/ |
内置技能模板 |
/app/extensions/ |
内置扩展 |
/app/openclaw.mjs |
主入口文件 |
4. 关键文件说明
4.1 核心配置
| 文件 | 容器内路径 | 作用 |
|---|---|---|
| 主配置 | /home/node/.openclaw/openclaw.json |
Gateway 端口/绑定/auth、模型、插件、频道、工具策略 |
| 配置备份 | /home/node/.openclaw/openclaw.json.bak* |
自动备份,修改出错可回滚 |
| 运行日志 | /tmp/openclaw/openclaw-YYYY-MM-DD.log |
容器内运行时日志,重启丢失 |
4.2 Agent 工作区
| 文件 | 容器内路径 | 作用 |
|---|---|---|
| IDENTITY.md | workspace/IDENTITY.md |
Agent 身份:名字、角色、性格 |
| SOUL.md | workspace/SOUL.md |
Agent 行为准则:价值观、决策逻辑 |
| AGENTS.md | workspace/AGENTS.md |
多 Agent 定义及能力描述 |
| TOOLS.md | workspace/TOOLS.md |
Agent 可调用工具授权 |
| BOOTSTRAP.md | workspace/BOOTSTRAP.md |
Agent 启动引导流程 |
| HEARTBEAT.md | workspace/HEARTBEAT.md |
定时心跳任务定义 |
| USER.md | workspace/USER.md |
用户画像与偏好 |
| state/ | workspace/state/ |
会话状态持久化 |
| .git/ | workspace/.git/ |
版本控制,支持回滚 |
4.3 插件与频道
| 路径 | 作用 |
|---|---|
extensions/ |
已安装插件(openclaw-weixin 等) |
agents/ |
Agent 认证配置、auth-profiles |
devices/ |
已配对设备信息 |
qqbot/ |
QQ 机器人频道配置 |
tasks/ |
定时任务执行记录 |
cron/jobs.json |
Cron 任务定义 |
canvas/ |
Control UI 前端静态资源 |
identity/ |
Gateway 自身身份凭证 |
logs/ |
Gateway 运行日志 |
5. 当前配置详情
5.1 Gateway 配置
{
"gateway": {
"auth": {
"mode": "token",
"token": "84b9255b705682edf22d0804d004f8060349067513dec98a"
},
"controlUi": {
"allowInsecureAuth": true,
"dangerouslyDisableDeviceAuth": true
},
"mode": "local",
"port": 18789,
"bind": "lan"
}
}
5.2 模型配置
| 项目 | 值 |
|---|---|
| 主模型 | minimax-portal/MiniMax-M2.7 |
| API 端点 | https://api.minimaxi.com/anthropic |
| API 协议 | anthropic-messages (Anthropic 兼容) |
| 上下文窗口 | 204,800 tokens |
| 最大输出 | 131,072 tokens |
| 推理能力 | 支持(reasoning: true) |
| 认证方式 | MiniMax OAuth CN(minimax-portal) |
| 订阅计划 | Plus(含图像理解) |
5.3 图像理解
| 项目 | 值 |
|---|---|
| 状态 | ✅ 已启用 |
| 实现方式 | minimax-portal 插件内置 registerMediaUnderstandingProvider |
| 视觉模型 | MiniMax-VL-01(插件内部路由) |
| 启用方式 | 通过 openclaw onboard --auth-choice minimax-cn-oauth 完成 OAuth 认证后自动生效 |
| 注意 | 日志中 [media-understanding] image: failed (0/1) reason=Unknown model 为已知噪音,不影响实际图像识别功能 |
💡 关键说明:MiniMax 图像理解仅在
minimax-portal(OAuth)认证方式下自动生效。使用 API Key(minimaxprovider)方式时,VL-01 不会被自动注册,图像理解不可用。如需启用,必须通过 OAuth 重新认证:docker exec -it openclaw openclaw onboard --auth-choice minimax-cn-oauth
5.4 插件状态
| 插件 | 版本 | 状态 |
|---|---|---|
| minimax | - | ✅ 已启用 |
| openclaw-weixin | 2.1.8 | ✅ 已启用 |
5.5 工具与策略
| 项目 | 值 |
|---|---|
| tools.profile | coding |
| agents.defaults.compaction.mode | safeguard |
| session.dmScope | per-channel-peer |
5.6 浏览器配置 (browser)
| 配置项 | 值 | 说明 |
|---|---|---|
browser.enabled |
true | 启用浏览器能力 |
browser.defaultProfile |
browserless | 默认 profile |
browser.profiles.browserless.cdpUrl |
ws://browserless:3000 |
连向 browserless sidecar(用容器名,避免 IP 漂移) |
browser.ssrfPolicy.dangerouslyAllowPrivateNetwork |
true | 允许 CDP 连接私网主机 |
browser.ssrfPolicy.hostnameAllowlist |
["*"] |
通配符放行所有域名(内网环境,无需逐个添加) |
browser.ssrfPolicy.allowedHostnames |
["*"] |
与 hostnameAllowlist 同步 |
browser.remoteCdpTimeoutMs |
30000 | CDP 整体超时(默认 15000 偏短) |
browser.remoteCdpHandshakeTimeoutMs |
45000 | CDP 握手超时 |
参考片段(openclaw.json):
{
"browser": {
"enabled": true,
"defaultProfile": "browserless",
"remoteCdpTimeoutMs": 30000,
"remoteCdpHandshakeTimeoutMs": 45000,
"profiles": {
"browserless": { "cdpUrl": "ws://browserless:3000", "color": "#00AA00" }
},
"ssrfPolicy": {
"dangerouslyAllowPrivateNetwork": true,
"hostnameAllowlist": ["*"],
"allowedHostnames": ["*"]
}
}
}
使用
["*"]通配符放行所有域名,无需逐个添加。如需收紧策略,改回逐域名白名单(修改时必须带齐所有值,否则会把browserless等关键主机顶掉)。
6. 访问方式
| 方式 | 地址 | 说明 |
|---|---|---|
| Control UI | http://192.168.0.130:18789/ |
浏览器访问,需输入 Gateway Token |
| 健康检查 | http://192.168.0.130:18789/healthz |
返回 {"ok":true,"status":"live"} |
| 就绪检查 | http://192.168.0.130:18789/readyz |
返回就绪状态 |
| SSH 隧道 | ssh -L 18789:127.0.0.1:18789 Tyrone@192.168.0.130 |
通过 localhost 安全访问 |
7. 常用运维命令
7.1 状态检查
# 容器运行状态
docker ps --filter name=openclaw
# 健康检查
curl -fsS http://192.168.0.130:18789/healthz
# 就绪检查
curl -fsS http://192.168.0.130:18789/readyz
# 资源占用
docker stats openclaw --no-stream
# 查看日志
docker logs --tail 50 openclaw
docker logs -f openclaw
# 容器详情
docker inspect openclaw --format='状态: {{.State.Status}} | 启动: {{.State.StartedAt}} | 健康: {{.State.Health.Status}}'
7.2 配置修改
⚠️ 变更前必备份:每次修改
openclaw.json、.env等关键配置前,必须先备份当前版本,以便出错时回滚。# 备份配置(带日期标记) sudo cp /volume1/docker/openclaw-data/openclaw.json /volume1/docker/openclaw-data/openclaw.json.bak-$(date +%Y%m%d) # 回滚到备份版本 sudo cp /volume1/docker/openclaw-data/openclaw.json.bak-YYYYMMDD /volume1/docker/openclaw-data/openclaw.json docker restart openclaw
# 修改单个配置
docker exec openclaw node dist/index.js config set --batch-json '[{"path":"<配置路径>","value":"<值>"}]'
# 查看当前配置
docker exec -u root openclaw cat /home/node/.openclaw/openclaw.json
# 宿主机直接编辑配置(需 sudo)
sudo vi /volume1/docker/openclaw-data/openclaw.json
7.3 容器管理
# 重启
docker restart openclaw
# 停止
docker stop openclaw
# 启动
docker start openclaw
# 进入容器(普通用户)
docker exec -it openclaw sh
# 进入容器(root 用户)
docker exec -it -u root openclaw sh
7.4 文件权限修复
# docker cp 后文件属主变为宿主机用户,需修复
docker exec -u root openclaw chown -R node:node /home/node/.openclaw
8. 升级流程
# 1. 备份配置
docker cp openclaw:/home/node/.openclaw /volume1/docker/openclaw-backup-$(date +%Y%m%d)
# 2. 拉取最新镜像
docker pull docker.1ms.run/alpine/openclaw:latest
# 3. 停止并删除旧容器
docker stop openclaw && docker rm openclaw
# 4. 用新镜像重建
docker run -d \
--name openclaw \
--restart always \
-p 18789:18789 \
-v /volume1/docker/openclaw-data:/home/node/.openclaw \
-e PUID=1026 \
-e PGID=100 \
docker.1ms.run/alpine/openclaw:latest
# 5. 修复文件权限
docker exec -u root openclaw chown -R node:node /home/node/.openclaw
# 6. 验证
sleep 15
docker logs --tail 10 openclaw
curl -fsS http://192.168.0.130:18789/healthz
9. 微信频道配置
# 扫码登录(交互式,需终端执行)
docker exec -it openclaw node dist/index.js channels login --channel openclaw-weixin
# 重启生效
docker restart openclaw
# 验证频道状态
docker exec openclaw node dist/index.js channels status
10. 已知问题与注意事项
10.1 安全配置
- ⚠️
allowInsecureAuth=true:允许 HTTP 非安全上下文认证 - ⚠️
dangerouslyDisableDeviceAuth=true:禁用设备身份验证,任何能访问 18789 端口的人可通过 token 控制 - 建议:配置 HTTPS 反向代理后,将以上两项恢复为
false
10.2 权限陷阱
/root/目录默认权限drwx------,node 用户无法穿越- Volume 必须映射到
/home/node/.openclaw,不要映射到/root/.openclaw docker cp备份后文件属主变为宿主机用户,需chown -R node:node修复
10.3 网络配置
gateway.bind必须设为lan(NAS 部署场景),否则局域网无法访问gateway.auth.mode必须为token,不要设为trusted-proxy(除非配置了 trustedProxy)
10.4 待完成事项
- 升级至 v2026.4.14
- 配置微信频道扫码登录
- 把
browser工具曝露给 Agent(tools.profile=coding不含 browser,需定位正确键名) - 按业务需求补齐
browser.ssrfPolicy.hostnameAllowlist - 轮换
gateway.auth.token(历史排障期间 token 曾外泄至日志) - 配置 HTTPS 反向代理(长期方案)
- 关闭
dangerouslyDisableDeviceAuth(HTTPS 配置完成后) - 运行
openclaw security audit安全审计
11. 故障排查
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 容器退出 (exit 137) | 内存不足 OOM | 确保 ≥4GB 可用 RAM |
| 健康检查失败 | 端口映射或 bind 配置错误 | 检查 -p 18789:18789 和 gateway.bind=lan |
| Gateway 启动失败循环 | auth 模式配置错误 | sudo sed 修复 openclaw.json 中的 auth.mode |
| Control UI "缺少网关令牌" | 正常认证流程 | 输入 openclaw.json 中的 gateway.auth.token |
| Control UI "需要设备身份" | HTTP 非安全上下文 | 设置 dangerouslyDisableDeviceAuth=true 或使用 SSH 隧道 |
| 配置修改 Permission denied | node 用户无写权限 | docker exec -u root openclaw chown -R node:node /home/node/.openclaw |
| pricing bootstrap failed | 网络问题 | 检查容器网络连通性,不影响核心功能 |
Remote CDP not reachable at ws://browserless:3000 (ms 级同步失败) |
browserless 主机名未加入 SSRF allowlist |
把 browserless 与 172.18.0.3 加入 browser.ssrfPolicy.hostnameAllowlist / allowedHostnames(两键同步) |
Remote CDP not reachable (约 15 秒超时失败) |
browserless 并发不足或超时过短 | 用 12.2 的参数重建 browserless,并把 CDP 超时放宽(见 5.5) |
Remote CDP not reachable 且 /json/version 返回 403 |
browserless 启用了 TOKEN |
去掉 TOKEN 环境变量,改由 Docker 网络隔离 |
browser CLI 子命令不存在 |
plugins.allow 未包含 browser |
把 browser 加入 plugins.allow 并重启 |
browser navigation blocked by policy |
目标域名未在 SSRF allowlist | 将目标域名加入 browser.ssrfPolicy.hostnameAllowlist |
browser status 显示 running:false 但 tabs 正常 |
Remote CDP 模式下 status 只读托管状态 |
忽略 status,以 tabs/open 为准(非 bug) |
| Agent 在 Control UI 里自称"没有 browser 工具" | tools.profile=coding 预设不含 browser |
待定位正确键名(见 10.4 待办) |
Model does not support images: minimax/MiniMax-M2.7 |
使用 API Key 认证(minimax provider),VL-01 未注册 |
切换到 OAuth 认证(见 §14) |
[media-understanding] image: failed (0/1) reason=Unknown model |
Gateway 模型查找路径找不到 VL-01 | 已知日志噪音,不影响实际图像识别(见 §14.4) |
[bundle-mcp] failed to start server "minimax-vision" |
MCP server 超时(uvx 首次下载包) | 不需要 MCP server,OAuth 方式自动处理(见 §14.3) |
config reload skipped: Unrecognized key: "mediaModel" |
agents.defaults.mediaModel 不是合法配置项 |
用 openclaw doctor --fix 清除,或手动删除 |
config reload skipped: Unrecognized key: "imageModel" |
agents.defaults.imageModel 指向不存在的模型 |
删除该配置项,让插件自动路由(见 §14.4) |
12. 浏览器能力(Remote CDP + Browserless)排障与调优
12.1 工作原理与关键事实
- OpenClaw 自身不内置 Chrome,浏览器能力通过 Remote CDP 连接外部
browserless容器实现。 browser插件需在plugins.allow列出并启用(browser.enabled=true),重启后browser才会出现在 CLI 顶层命令。- OpenClaw 会在发起连接前同步校验
cdpUrl的主机:- IP 形式(如
172.18.0.3)走dangerouslyAllowPrivateNetwork私网放行 - 主机名形式(如
browserless)必须进入hostnameAllowlist/allowedHostnames - 未通过校验时错误统一为
Remote CDP ... not reachable,失败耗时在 毫秒级(与网络超时区分关键特征)
- IP 形式(如
- OpenClaw 对 browserless 的可达性探测会请求
/json/version但不附带 token,因此 browserless 必须关闭 TOKEN。 browser status在 Remote CDP 模式下始终显示running:false(它读的是"托管会话"状态),以tabs/open为准。
12.2 一次到位的部署配置(生产建议值)
Browserless:
sudo mkdir -p /volume1/docker/browserless-profile
sudo chmod -R 777 /volume1/docker/browserless-profile
docker run -d --name browserless --restart always \
--network openclaw-net \
-v /volume1/docker/browserless-profile:/profile \
-e MAX_CONCURRENT_SESSIONS=10 \
-e KEEP_ALIVE=true \
-e CONNECTION_TIMEOUT=600000 \
-e DEFAULT_USER_DATA_DIR=/profile \
-e DEFAULT_STEALTH=true \
browserless/chrome:latest
OpenClaw 端(plugins.allow 含 browser,且已应用 5.5 的 browser 配置):
docker exec openclaw node dist/index.js config set --batch-json '[
{"path":"plugins.allow","value":["openclaw-weixin","minimax","memory-core","browser"]},
{"path":"browser.profiles.browserless.cdpUrl","value":"ws://browserless:3000"},
{"path":"browser.remoteCdpTimeoutMs","value":30000},
{"path":"browser.remoteCdpHandshakeTimeoutMs","value":45000},
{"path":"browser.ssrfPolicy.dangerouslyAllowPrivateNetwork","value":true},
{"path":"browser.ssrfPolicy.hostnameAllowlist","value":["*"]},
{"path":"browser.ssrfPolicy.allowedHostnames","value":["*"]}
]'
docker restart openclaw
12.3 三层验证
第 1 层:网络/CDP 协议可用性(openclaw 容器内执行)
# HTTP 无 token 必须 200
docker exec openclaw node -e "
(async () => {
const r = await fetch('http://browserless:3000/json/version');
console.log('status=', r.status);
})();"
# WebSocket CDP 握手必须有 Browser.getVersion 回包
docker exec openclaw node -e "
const WebSocket=require('ws');
const ws=new WebSocket('ws://browserless:3000');
ws.on('open',()=>ws.send(JSON.stringify({id:1,method:'Browser.getVersion'})));
ws.on('message',(d)=>{console.log('REPLY',d.toString()); process.exit(0);});
ws.on('error',(e)=>{console.error('ERR',e.message); process.exit(1);});
setTimeout(()=>{console.error('TIMEOUT');process.exit(2);},15000);"
第 2 层:OpenClaw CLI 闭环
docker exec openclaw node dist/index.js browser --browser-profile browserless start
docker exec openclaw node dist/index.js browser --browser-profile browserless open https://example.com
docker exec openclaw node dist/index.js browser --browser-profile browserless tabs
docker exec openclaw node dist/index.js browser --browser-profile browserless snapshot
第 3 层:稳定性(连续独立调用)
for i in 1 2 3; do
echo "---- round $i ----"
docker exec openclaw node dist/index.js browser --browser-profile browserless open https://example.com
done
三轮全部返回 opened: https://example.com/ 才算稳定闭环。
12.4 历史定位过程(本次排障复盘)
| # | 现象 | 根因 | 修复 |
|---|---|---|---|
| 1 | Remote CDP not reachable(ms 级) |
cdpUrl 用容器名 browserless,但未入 hostnameAllowlist |
将 browserless 加入 allowlist(两个键同步) |
| 2 | Remote CDP not reachable(/json/version 403) |
browserless 启用了 TOKEN,OpenClaw 探测不带 token |
去掉 TOKEN 环境变量,改由网络隔离 |
| 3 | 独立 CLI 调用 open 间歇性 15s 超时失败 |
browserless 并发不足、OpenClaw 超时偏短 | 扩容 MAX_CONCURRENT_SESSIONS=10 + KEEP_ALIVE + remoteCdpTimeoutMs=30000 |
| 4 | status 显示 running:false 但 tabs 正常 |
Remote CDP 模式 status 只读托管状态 |
非 bug,忽略 status |
| 5 | Agent 在 UI 里说"没有 browser 工具" | tools.profile=coding 预设不含 browser(待定位 key) |
见 10.4 待办 |
| 6 | Chrome 报 SingletonLock: File exists 或 Permission denied |
PREBOOT_CHROME 多实例争抢同一 profile 目录,或群晖权限过严 |
去掉 PREBOOT_CHROME/PREBOOT_QUANTITY,sudo chmod -R 777 目录,清除残留锁文件 |
12.5 Browserless 容器常用运维
# 查看 IP(通常稳定为 openclaw-net 内第 3 个 IP)
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' browserless
# 查看是否启用 TOKEN(必须 NO_TOKEN_ENV)
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' browserless | grep -E '^TOKEN=' || echo "NO_TOKEN_ENV"
# 查看 browserless 日志
docker logs --tail 100 browserless
# 重建 browserless(保持运维建议参数,见 12.2)
docker stop browserless && docker rm browserless
# 再执行 12.2 的 run 命令
12.6 Browserless 重装速查清单
多次排障经验汇总,重装时按此清单逐项检查,避免重复踩坑。
步骤 1:创建持久化目录(必须在 docker run 之前)
sudo mkdir -p /volume1/docker/browserless-profile
sudo chown -R 1000:1000 /volume1/docker/browserless-profile
sudo chmod -R 777 /volume1/docker/browserless-profile # 群晖必须!否则 Chrome 报 Permission denied
⚠️ 如果目录不存在就执行
docker run -v ...,Docker 会静默忽略挂载参数,Binds为 null,profile 不持久化。
验证:ls -ld /volume1/docker/browserless-profile/ 必须返回目录信息。
步骤 2:清除残留锁文件(重启/重装前)
sudo rm -rf /volume1/docker/browserless-profile/SingletonLock \
/volume1/docker/browserless-profile/SingletonCookie \
/volume1/docker/browserless-profile/SingletonSocket
⚠️ 不清理会导致 Chrome 报
SingletonLock: File exists启动失败。
步骤 3:创建容器
docker run -d --name browserless --restart always \
--network openclaw-net \
-v /volume1/docker/browserless-profile:/profile \
-e MAX_CONCURRENT_SESSIONS=10 \
-e KEEP_ALIVE=true \
-e CONNECTION_TIMEOUT=600000 \
-e DEFAULT_USER_DATA_DIR=/profile \
-e DEFAULT_STEALTH=true \
browserless/chrome:latest
⚠️ 不要使用
PREBOOT_CHROME=true/PREBOOT_QUANTITY=2:预热会启动多个 Chrome 实例,与DEFAULT_USER_DATA_DIR共享同一 profile 目录时触发SingletonLock互斥锁冲突,导致 Chrome 启动失败报Issue launching Chrome, retries exhausted。KEEP_ALIVE=true已能保证会话间复用。
⚠️ 不要设置
TOKEN环境变量:OpenClaw 可达性探测请求/json/version不带 token,启用 TOKEN 导致 403 → 被误判为Remote CDP not reachable。
步骤 4:验证挂载生效
docker inspect browserless --format='{{json .HostConfig.Binds}}'
# 必须返回: ["/volume1/docker/browserless-profile:/profile"]
# 如果返回 null → 目录不存在时创建的容器,需删除重建
docker exec browserless ls -la /profile/
# 必须返回目录列表(首次为空但能看到 . 和 ..)
步骤 5:等待 Chrome 启动
sleep 15 && docker logs --tail 10 browserless
# 必须看到 "Running on port 3000" 或 "Chrome launched"
# 如果看到 "Issue launching Chrome, retries exhausted" → 检查权限/锁文件
步骤 6:配置 OpenClaw SSRF 策略
docker exec openclaw node dist/index.js config set --batch-json '[
{"path":"browser.ssrfPolicy.dangerouslyAllowPrivateNetwork","value":true},
{"path":"browser.ssrfPolicy.hostnameAllowlist","value":["*"]},
{"path":"browser.ssrfPolicy.allowedHostnames","value":["*"]}
]'
docker restart openclaw
⚠️ SSRF allowlist 会在 OpenClaw 重启时被清空为
[](已知行为)。如果open报not reachable且耗时 ~140ms(毫秒级),就是 SSRF 拦截,不是真正的网络问题。重新执行上述命令即可。
步骤 7:端到端验证
# 第 1 层:HTTP 可达
docker exec openclaw node -e "
(async () => {
const r = await fetch('http://browserless:3000/json/version');
console.log('status=', r.status);
})();"
# 期望: status= 200
# 第 2 层:WebSocket CDP 握手
docker exec openclaw node -e "
const WebSocket=require('ws');
const ws=new WebSocket('ws://browserless:3000');
ws.on('open',()=>ws.send(JSON.stringify({id:1,method:'Browser.getVersion'})));
ws.on('message',(d)=>{console.log('REPLY',d.toString()); process.exit(0);});
ws.on('error',(e)=>{console.error('ERR',e.message); process.exit(1);});
setTimeout(()=>{console.error('TIMEOUT');process.exit(2);},15000);"
# 期望: REPLY {"id":1,"result":{...}}
# 第 3 层:OpenClaw CLI 闭环
docker exec openclaw node dist/index.js browser --browser-profile browserless open https://www.baidu.com
# 期望: opened: https://www.baidu.com/
故障速判表
| 现象 | 耗时 | 根因 | 修复 |
|---|---|---|---|
ECONNREFUSED |
- | browserless 未启动或端口不通 | docker logs browserless 检查启动状态 |
Permission denied 创建 SingletonLock |
- | /profile/ 权限不足 |
sudo chmod -R 777 /volume1/docker/browserless-profile |
SingletonLock: File exists |
- | 残留锁文件 | sudo rm -rf .../SingletonLock .../SingletonCookie .../SingletonSocket |
Issue launching Chrome, retries exhausted |
- | PREBOOT 多实例锁冲突 | 去掉 PREBOOT_CHROME/PREBOOT_QUANTITY |
Binds: null |
- | 目录不存在时创建容器 | 先 mkdir + chmod,再 docker run |
not reachable + ~140ms |
毫秒级 | SSRF 策略拦截 | 重新设置 hostnameAllowlist: ["*"] |
not reachable + 403 |
- | browserless 启用了 TOKEN | 去掉 TOKEN 环境变量 |
not reachable + 15s+ |
秒级 | 真正的网络/超时问题 | 检查容器网络、CDP 超时配置 |
13. Agent 人设与 Workspace 维护
本章记录 OpenClaw Agent(代号 小橙)的长期记忆结构与维护流程。源文件在 w:\ProRepo\NASOpenClaw\workspace\(本地 Git 管理),部署到容器内 /home/node/.openclaw/workspace/(宿主机 /volume1/docker/openclaw-data/workspace/)。
13.1 Workspace 目录语义
| 路径 | 作用 | 维护者 |
|---|---|---|
README.md |
Workspace 总说明 | Tyrone |
USER.md |
主人画像、公司档案、合规红线、渠道矩阵、KPI | Tyrone |
IDENTITY.md |
小橙的身份、职责、边界 | Tyrone |
SOUL.md |
小橙的决策准则与行为规约(最重要的运行时提示) | Tyrone |
AGENTS.md |
多 Agent / 多技能分工 | Tyrone |
TOOLS.md |
工具授权与使用准则 | Tyrone |
BOOTSTRAP.md |
启动引导与自检 | Tyrone |
HEARTBEAT.md |
定时心跳任务定义 | Tyrone |
insights.md |
经验沉淀(小橙随反馈持续追加) | 小橙 |
brand/voice-style.md |
文笔风格规约(产业观察笔法) | Tyrone |
brand/banned-words.md |
广告法 / 行业合规禁用词库 | Tyrone |
products/README.md |
产品与解决方案线索引 | Tyrone |
products/_template.md |
产品页模板 | — |
products/*.md |
各方案详情页(数据源) | Tyrone |
templates/*.md |
21 个平台发文模板 | Tyrone |
assets/ |
媒体素材(图片 / 视频 / PPT) | Tyrone |
drafts/ |
待复核草稿(小橙产出) | 小橙 |
published/ |
已发布归档 + 链接 + 数据快照 | 小橙 |
reports/ |
日报 / 周报 / 复盘 | 小橙 |
state/ |
会话状态、API 调用日志 | OpenClaw 自动 |
13.2 推送到 NAS 容器(首次部署)
本地 workspace/ 编辑完成后,推送到 NAS:
# 方式 A:scp 整个目录(推荐首次使用)
scp -r w:/ProRepo/NASOpenClaw/workspace Tyrone@192.168.0.130:/tmp/workspace-new
# SSH 到 NAS 后
ssh Tyrone@192.168.0.130
sudo mv /volume1/docker/openclaw-data/workspace /volume1/docker/openclaw-data/workspace.bak-$(date +%Y%m%d) 2>/dev/null
sudo mv /tmp/workspace-new /volume1/docker/openclaw-data/workspace
# 修复权限(容器内 node:node)
docker exec -u root openclaw chown -R node:node /home/node/.openclaw/workspace
# 初始化 workspace 下的 git(便于版本管理)
docker exec -u node openclaw sh -c "cd /home/node/.openclaw/workspace && git init && git add -A && git commit -m 'init: workspace scaffolding'"
# 重启生效
docker restart openclaw
13.3 推送到 NAS 容器(日常增量更新)
改动某几个 md 文件后:
# 本地改完先 git commit 记录
cd w:/ProRepo/NASOpenClaw
git add workspace/
git commit -m "update: <what changed>"
# 用 rsync 增量同步(省带宽、保留容器侧 drafts/published/)
rsync -av --delete \
--exclude 'drafts/' --exclude 'published/' --exclude 'reports/' \
--exclude 'state/' --exclude '.git/' --exclude 'assets/' \
w:/ProRepo/NASOpenClaw/workspace/ \
Tyrone@192.168.0.130:/volume1/docker/openclaw-data/workspace/
# 修复权限
ssh Tyrone@192.168.0.130 "docker exec -u root openclaw chown -R node:node /home/node/.openclaw/workspace"
# 通知小橙重读(不用重启容器,小橙下一轮对话自动读取)
注意:
drafts/published/reports/state/由小橙在容器内写入,本地不保留,rsync 必须加--exclude,否则会被回覆盖。
13.4 日常维护节奏
| 频率 | 动作 | 负责 |
|---|---|---|
| 每次调教后 | 本地改 USER/IDENTITY/SOUL → rsync → 生效 | Tyrone |
| 每周一次 | 审阅 insights.md,把重要经验固化进 SOUL.md 或 voice-style.md |
Tyrone |
| 每月一次 | 审阅 products/ 是否补齐新案例 |
Tyrone |
| 每季度一次 | 审阅 templates/ 平台政策是否变化(发布流程、话题标签、合规规则) |
Tyrone |
| 随时 | Git 提交 + 推送到 GitHub/Gitea 做异地备份 | Tyrone |
13.5 首次启动后必做的事
- 在
products/下至少建 3 个方案页(建议mes.md/scada.md/machine-vision.md)。 - 在 Control UI 跟小橙说:"自检",确认
BOOTSTRAP.md的 4 项自检全过。 - 给各社交/电商平台挨个扫码登录(由 Tyrone 手动完成),登录态存在
/volume1/docker/browserless-profile/(需先按本文 §13.6 重建 browserless 启用持久化 profile)。 - 用一轮真实选题测试小橙的产出质量,依据反馈修订
voice-style.md与insights.md。
13.6 Browserless 重建(启用持久化登录态 + Stealth)
为让四大平台(小红书 / 抖音 / 淘宝 / LinkedIn 等)登录态长期保留,需重建 browserless:
# 停止旧容器
docker stop browserless && docker rm browserless
# 创建持久化 profile 目录(NAS 宿主机)
sudo mkdir -p /volume1/docker/browserless-profile
sudo chown -R 1000:1000 /volume1/docker/browserless-profile
sudo chmod -R 777 /volume1/docker/browserless-profile # 群晖必须,否则 Chrome 报 Permission denied
# 清除残留锁文件(如有)
sudo rm -f /volume1/docker/browserless-profile/SingletonLock
# 重建(带 stealth + 持久化 profile,不预热避免 SingletonLock 冲突)
docker run -d --name browserless --restart always \
--network openclaw-net \
-v /volume1/docker/browserless-profile:/profile \
-e MAX_CONCURRENT_SESSIONS=10 \
-e KEEP_ALIVE=true \
-e CONNECTION_TIMEOUT=600000 \
-e DEFAULT_USER_DATA_DIR=/profile \
-e DEFAULT_STEALTH=true \
browserless/chrome:latest
13.7 配置 SSRF Allowlist
内网环境使用通配符放行所有域名,无需逐个添加:
docker exec openclaw node dist/index.js config set --batch-json '[
{"path":"browser.ssrfPolicy.dangerouslyAllowPrivateNetwork","value":true},
{"path":"browser.ssrfPolicy.hostnameAllowlist","value":["*"]},
{"path":"browser.ssrfPolicy.allowedHostnames","value":["*"]}
]'
docker restart openclaw
如需收紧策略,改回逐域名白名单。注意:
hostnameAllowlist/allowedHostnames是整体覆盖类配置,修改时必须带齐所有值(含browserless),否则会把关键主机顶掉导致 CDP 连接失败。
13.8 把 browser 工具曝露给默认 Agent
当前 tools.profile=coding 不含 browser(见 §10.4 待办)。可切换到通用 profile:
# 方案 A(整体切换 profile,推荐先试)
docker exec openclaw node dist/index.js config set --batch-json '[
{"path":"tools.profile","value":"general"}
]'
docker restart openclaw
# 在 Control UI 里让小橙执行 "browser tabs" 验证是否可见
# 若 general 也不含,改用方案 B:在 Agent 配置里单独加 allowedTools(通过 UI 或 config 具体 key 待定位)
13.9 小橙对话 / 指令范式速查
下列为 Tyrone 在 Control UI 与小橙交互时的高频指令模板。小橙在 SOUL.md 与 HEARTBEAT.md 中对应了这些关键词的行为。
13.9.1 日常启动 / 状态
| 指令 | 触发行为 |
|---|---|
自检 |
小橙执行 BOOTSTRAP.md 四项自检并回报 |
今天干什么 |
拉待复核草稿 + 昨日数据 + 今日待办(等同 Heart beat 开场白) |
小橙休假 |
挂起所有心跳任务,仅保留 inbox-sweep |
小橙上班 |
恢复全部心跳 |
13.9.2 选题与内容生产
| 指令 | 触发行为 |
|---|---|
给我 3 个选题 / 本周选题 |
产出 3 候选,等 Tyrone 回"选 N" |
追热点 <关键词> |
立即抓取该方向热点,产出 3 候选 |
写 <选题> |
进入母版生成流程(先出 3 个标题 + 大纲) |
这版不行,<原因> |
重写并把反馈沉淀到 insights.md |
改成 <平台> |
按目标平台模板改写母版 |
一稿多发 <主题> |
按 USER.md §5 矩阵全覆盖改写 |
13.9.3 发布与复核
| 指令 | 触发行为 |
|---|---|
待复核 |
列出 drafts/ 所有未发稿,分平台展示 |
预览 <文件名> |
展示完整稿件 |
确认发布 <文件名> |
进入发布执行流程,停在"发布"按钮前 |
一键发布今日所有草稿 |
批量进入发布流程(每篇仍停在发布前等 Tyrone 点) |
撤 <平台> <主题> |
从 published 找对应稿件,提示 Tyrone 手动撤回(小橙不碰删除) |
风险停机 |
立即停所有自动任务,进入只读模式 |
13.9.4 数据与复盘
| 指令 | 触发行为 |
|---|---|
数据 / 昨天数据 |
产出简版日报 |
本周复盘 |
产出周报(不等 cron) |
哪条最火 |
列近 7 天 Top3 文 / 视频 |
小红书最近怎么样 |
单平台 7 天纵览 |
13.9.5 知识沉淀与调教
| 指令 | 触发行为 |
|---|---|
记住:<规则> |
追加到 insights.md + memory-core |
以后都这样做 |
同上,但归入"永久规则"段 |
忘掉 <规则> |
从 insights.md 标注为已废弃(不删,只标注) |
读一下 products/mes.md |
小橙重新加载指定文件作为当前上下文 |
13.9.6 线索与商机
| 指令 | 触发行为 |
|---|---|
今天有询盘吗 |
从 inbox-sweep 结果里筛命中 报价/合作/定制/方案 的对话 |
跟进 <客户标识> |
生成 WhatsApp / LinkedIn 跟进话术草稿 |
新增客户线索:<公司> <需求> |
写入 memory-core + insights.md |
13.9.7 异常时的求助句式(Tyrone 可参考)
小橙别慌,<问题描述>— 小橙进入"只读 + 诊断"模式,只分析不动手停!— 立即终止当前所有任务,等下一条指令回答我就好,不要动手— 本轮只对话不执行工具调用
13.10 待完成事项(接力自 §10.4)
- 首次推送 workspace 到 NAS(§13.2)
- 按 §13.5 补齐至少 3 个
products/*.md - 按 §13.6 重建 browserless 启用持久化 profile + stealth
- 按 §13.7 批量补齐 SSRF allowlist
- 按 §13.8 把
browser工具曝露给默认 Agent - 各社交/电商平台在 browserless profile 内挨个扫码登录
- 配置
cron/jobs.json对应HEARTBEAT.md的心跳任务
14. MiniMax 图像理解排障专题
2026-04-21 排障复盘。从"Model does not support images"到成功启用图像理解,历时约 2 小时。
14.1 核心结论
| 认证方式 | Provider ID | 图像理解 | 说明 |
|---|---|---|---|
| API Key | minimax |
❌ 不可用 | VL-01 不被注册,Gateway 丢弃图片 |
| OAuth CN | minimax-portal |
✅ 自动生效 | 插件通过 registerMediaUnderstandingProvider 内部路由 VL-01 |
唯一正确路径:通过 minimax-cn-oauth 完成 OAuth 认证,切换到 minimax-portal provider,图像理解自动生效。
14.2 当前配置状态(2026-04-21)
| 项目 | 值 |
|---|---|
| 主模型 | minimax-portal/MiniMax-M2.7 |
| 认证方式 | MiniMax OAuth CN |
| 订阅计划 | Plus(含图像理解) |
| 图像理解 | ✅ 已启用(插件内部路由 MiniMax-VL-01) |
models list 显示 |
minimax-portal/MiniMax-M2.7(text)、minimax-portal/MiniMax-M2.7-highspeed(text) |
| VL-01 是否在 models list | 否(通过插件 registerMediaUnderstandingProvider 内部注册,不走模型目录) |
14.3 走过的弯路(避免重复)
| # | 尝试 | 结果 | 原因 |
|---|---|---|---|
| 1 | 在 models.providers.minimax.models 中添加 VL-01 |
❌ 模型不被注册 | MiniMax 插件启动时覆盖模型列表,手动添加被忽略 |
| 2 | 配置 tools.media.image 路由到 VL-01 |
❌ "Unknown model" | Gateway 找不到 VL-01 模型定义 |
| 3 | 配置 plugins.entries.minimax.config.vision |
❌ Schema 不允许 | config reload skipped: invalid config: must NOT have additional properties |
| 4 | 配置 agents.defaults.mediaModel |
❌ 不是合法配置项 | Unrecognized key: "mediaModel" |
| 5 | 创建独立 minimax-vision provider |
❌ "Unknown model" + 网络错误 | Token Plan API key 无法直接调用 VL-01 模型 API |
| 6 | 注册 minimax-coding-plan-mcp MCP server |
❌ 超时 30s | uvx 首次下载包耗时过长;且 OAuth 方式不需要此 MCP |
| 7 | 配置 agents.defaults.imageModel |
❌ "Unknown model" | 指向的模型在 models list 中不存在 |
| 8 | openclaw onboard --auth-choice minimax-cn-oauth |
✅ 成功 | OAuth 方式自动注册 registerMediaUnderstandingProvider |
14.4 已知遗留问题
[media-understanding] image: failed (0/1) reason=Unknown model
- 现象:每次发图片时,日志中出现此警告
- 影响:无。图片识别正常工作,minimax-portal 插件内部处理了图像理解
- 原因:Gateway 的模型查找路径尝试在模型目录中找 image-capable 模型,但 VL-01 不在
models list中(它通过插件 API 注册,不走模型目录) - 处理:可忽略。若要消除此日志,可在
minimax-portalprovider 下手动添加 VL-01 模型定义(见下方脚本)
# 可选:消除 Unknown model 日志噪音
sudo tee /tmp/fix-vl01.py > /dev/null << 'PYEOF'
import json
path='/volume1/docker/openclaw-data/openclaw.json'
d=json.load(open(path))
portal = d['models']['providers']['minimax-portal']
if not portal.get('models'):
portal['models'] = []
existing_ids = [m['id'] for m in portal['models']]
if 'MiniMax-VL-01' not in existing_ids:
portal['models'].append({
'id': 'MiniMax-VL-01',
'name': 'MiniMax VL-01',
'reasoning': False,
'input': ['text', 'image'],
'contextWindow': 131072,
'maxTokens': 4096
})
with open(path,'w') as f:
json.dump(d,f,indent=2,ensure_ascii=False)
print('Done')
PYEOF
sudo python3 /tmp/fix-vl01.py
docker restart openclaw
14.5 启用图像理解的完整步骤(从零开始)
如果未来需要重新配置,按以下步骤操作:
# 1. 备份当前配置
sudo cp /volume1/docker/openclaw-data/openclaw.json /volume1/docker/openclaw-data/openclaw.json.bak-$(date +%Y%m%d%H%M)
# 2. 执行 OAuth 认证(会打开浏览器授权)
docker exec -it openclaw openclaw onboard --auth-choice minimax-cn-oauth
# 终端会显示一个 URL,在浏览器中打开并授权
# 选择 "Update values" 保留现有配置
# 频道选择 "Skip for now"(微信已有)
# 3. 重启
docker restart openclaw
# 4. 验证
docker logs --tail 20 openclaw | grep "agent model"
# 应显示: agent model: minimax-portal/MiniMax-M2.7
# 5. 微信发图片测试
14.6 参考文档
- OpenClaw MiniMax Provider 文档
- OpenClaw Media Understanding 文档
- MiniMax Token Plan MCP Guide
- MiniMax OpenClaw 配置指南
- GitHub Issue #65283 — MiniMax Coding Plan image tool fails