Files
NASOpenClawRunTime/knowledge/OpenClaw-DS925-运维手册.md
小橙 5b9da9e70c feat: 工作姿态升级 v2 - 主动+自研模式
- IDENTITY.md §四: 新增主动思考+主动研究要求
- SOUL.md §一: 新增第4条(主动优于被动)+第5条(自研胜过求助)
- SOUL.md §六: 升级为3级决策框架
- HEARTBEAT.md: 新增主动触发场景表
- TOOLS.md §2.1/4.2: 补充运维脚本+搜索研究规则
- insights.md: 追加工作姿态升级反思
- knowledge/research-log.md: 新建研究沉淀文档
2026-04-21 10:11:28 +00:00

42 KiB
Raw Blame History

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/.openclawnode 用户 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 CNminimax-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-portalOAuth认证方式下自动生效。使用 API Keyminimax provider方式时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 必须设为 lanNAS 部署场景),否则局域网无法访问
  • gateway.auth.mode 必须为 token不要设为 trusted-proxy(除非配置了 trustedProxy

10.4 待完成事项

  • 升级至 v2026.4.14
  • 配置微信频道扫码登录
  • browser 工具曝露给 Agenttools.profile=coding 不含 browser需定位正确键名
  • 按业务需求补齐 browser.ssrfPolicy.hostnameAllowlist
  • 轮换 gateway.auth.token(历史排障期间 token 曾外泄至日志)
  • 配置 HTTPS 反向代理(长期方案)
  • 关闭 dangerouslyDisableDeviceAuthHTTPS 配置完成后)
  • 运行 openclaw security audit 安全审计

11. 故障排查

症状 可能原因 解决方案
容器退出 (exit 137) 内存不足 OOM 确保 ≥4GB 可用 RAM
健康检查失败 端口映射或 bind 配置错误 检查 -p 18789:18789gateway.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 browserless172.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:falsetabs 正常 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 providerVL-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 serverOAuth 方式自动处理(见 §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,失败耗时在 毫秒级(与网络超时区分关键特征)
  • 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.allowbrowser,且已应用 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 reachablems 级) cdpUrl 用容器名 browserless,但未入 hostnameAllowlist browserless 加入 allowlist两个键同步
2 Remote CDP not reachable/json/version 403 browserless 启用了 TOKENOpenClaw 探测不带 token 去掉 TOKEN 环境变量,改由网络隔离
3 独立 CLI 调用 open 间歇性 15s 超时失败 browserless 并发不足、OpenClaw 超时偏短 扩容 MAX_CONCURRENT_SESSIONS=10 + KEEP_ALIVE + remoteCdpTimeoutMs=30000
4 status 显示 running:falsetabs 正常 Remote CDP 模式 status 只读托管状态 非 bug忽略 status
5 Agent 在 UI 里说"没有 browser 工具" tools.profile=coding 预设不含 browser待定位 key 见 10.4 待办
6 Chrome 报 SingletonLock: File existsPermission denied PREBOOT_CHROME 多实例争抢同一 profile 目录,或群晖权限过严 去掉 PREBOOT_CHROME/PREBOOT_QUANTITYsudo 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 为 nullprofile 不持久化。

验证: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 exhaustedKEEP_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 重启时被清空为 [](已知行为)。如果 opennot 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

# 方式 Ascp 整个目录(推荐首次使用)
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.mdvoice-style.md Tyrone
每月一次 审阅 products/ 是否补齐新案例 Tyrone
每季度一次 审阅 templates/ 平台政策是否变化(发布流程、话题标签、合规规则) Tyrone
随时 Git 提交 + 推送到 GitHub/Gitea 做异地备份 Tyrone

13.5 首次启动后必做的事

  1. products/ 下至少建 3 个方案页(建议 mes.md / scada.md / machine-vision.md)。
  2. 在 Control UI 跟小橙说:"自检",确认 BOOTSTRAP.md 的 4 项自检全过。
  3. 给各社交/电商平台挨个扫码登录(由 Tyrone 手动完成),登录态存在 /volume1/docker/browserless-profile/(需先按本文 §13.6 重建 browserless 启用持久化 profile
  4. 用一轮真实选题测试小橙的产出质量,依据反馈修订 voice-style.mdinsights.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.mdHEARTBEAT.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.7textminimax-portal/MiniMax-M2.7-highspeedtext
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-portal provider 下手动添加 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 参考文档