801 lines
30 KiB
Markdown
801 lines
30 KiB
Markdown
# OpenClaw 群晖 NAS DS925+ 运维手册
|
||
|
||
> 最后更新:2026-04-18
|
||
> 维护者: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 创建容器命令
|
||
|
||
```bash
|
||
# 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 章)。
|
||
|
||
```bash
|
||
docker run -d \
|
||
--name browserless \
|
||
--restart always \
|
||
--network openclaw-net \
|
||
-e MAX_CONCURRENT_SESSIONS=10 \
|
||
-e PREBOOT_CHROME=true \
|
||
-e PREBOOT_QUANTITY=2 \
|
||
-e KEEP_ALIVE=true \
|
||
-e CONNECTION_TIMEOUT=600000 \
|
||
browserless/chrome:latest
|
||
```
|
||
|
||
参数说明:
|
||
|
||
| 环境变量 | 值 | 作用 |
|
||
|---------|-----|------|
|
||
| `MAX_CONCURRENT_SESSIONS` | 10 | 避免 OpenClaw 重连时被排队 |
|
||
| `PREBOOT_CHROME` | true | 预热 Chrome,降低冷启动延迟 |
|
||
| `PREBOOT_QUANTITY` | 2 | 保持 2 个预热实例 |
|
||
| `KEEP_ALIVE` | true | 空闲时不立即销毁,稳定连续请求 |
|
||
| `CONNECTION_TIMEOUT` | 600000 | 10 分钟空闲超时 |
|
||
|
||
> ⚠️ **禁止**设置 `TOKEN` 环境变量。OpenClaw 在可达性探测阶段会请求 `/json/version` 但**不带** token,启用 TOKEN 会导致 403 → 被误判为 `Remote CDP not reachable`。改由 Docker 网络隔离保障安全。
|
||
|
||
---
|
||
|
||
## 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 配置
|
||
|
||
```json
|
||
{
|
||
"gateway": {
|
||
"auth": {
|
||
"mode": "token",
|
||
"token": "84b9255b705682edf22d0804d004f8060349067513dec98a"
|
||
},
|
||
"controlUi": {
|
||
"allowInsecureAuth": true,
|
||
"dangerouslyDisableDeviceAuth": true
|
||
},
|
||
"mode": "local",
|
||
"port": 18789,
|
||
"bind": "lan"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.2 模型配置
|
||
|
||
| 项目 | 值 |
|
||
|------|-----|
|
||
| 主模型 | minimax/MiniMax-M2.7 |
|
||
| API 端点 | `https://api.minimaxi.com/anthropic` |
|
||
| API 协议 | anthropic-messages (Anthropic 兼容) |
|
||
| 上下文窗口 | 204,800 tokens |
|
||
| 最大输出 | 131,072 tokens |
|
||
| 推理能力 | 支持(reasoning: true) |
|
||
| 认证方式 | API Key(minimax:cn profile) |
|
||
|
||
### 5.3 插件状态
|
||
|
||
| 插件 | 版本 | 状态 |
|
||
|------|------|------|
|
||
| minimax | - | ✅ 已启用 |
|
||
| openclaw-weixin | 2.1.8 | ✅ 已启用(⚠️ 未配置,需扫码登录) |
|
||
|
||
### 5.4 工具与策略
|
||
|
||
| 项目 | 值 |
|
||
|------|-----|
|
||
| tools.profile | coding |
|
||
| agents.defaults.compaction.mode | safeguard |
|
||
| session.dmScope | per-channel-peer |
|
||
|
||
### 5.5 浏览器配置 (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` | 含 `browserless`、`172.18.0.3`、业务域名 | **必须包含 `browserless`**(见 12.1) |
|
||
| `browser.ssrfPolicy.allowedHostnames` | 同上 | 与 `hostnameAllowlist` 同步维护 |
|
||
| `browser.remoteCdpTimeoutMs` | 30000 | CDP 整体超时(默认 15000 偏短) |
|
||
| `browser.remoteCdpHandshakeTimeoutMs` | 45000 | CDP 握手超时 |
|
||
|
||
参考片段(`openclaw.json`):
|
||
|
||
```json
|
||
{
|
||
"browser": {
|
||
"enabled": true,
|
||
"defaultProfile": "browserless",
|
||
"remoteCdpTimeoutMs": 30000,
|
||
"remoteCdpHandshakeTimeoutMs": 45000,
|
||
"profiles": {
|
||
"browserless": { "cdpUrl": "ws://browserless:3000", "color": "#00AA00" }
|
||
},
|
||
"ssrfPolicy": {
|
||
"dangerouslyAllowPrivateNetwork": true,
|
||
"hostnameAllowlist": [
|
||
"example.com", "*.example.com",
|
||
"baidu.com", "*.baidu.com",
|
||
"browserless", "172.18.0.3"
|
||
],
|
||
"allowedHostnames": [
|
||
"example.com", "*.example.com",
|
||
"baidu.com", "*.baidu.com",
|
||
"browserless", "172.18.0.3"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
> ⚠️ `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 状态检查
|
||
|
||
```bash
|
||
# 容器运行状态
|
||
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 配置修改
|
||
|
||
```bash
|
||
# 修改单个配置
|
||
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 容器管理
|
||
|
||
```bash
|
||
# 重启
|
||
docker restart openclaw
|
||
|
||
# 停止
|
||
docker stop openclaw
|
||
|
||
# 启动
|
||
docker start openclaw
|
||
|
||
# 进入容器(普通用户)
|
||
docker exec -it openclaw sh
|
||
|
||
# 进入容器(root 用户)
|
||
docker exec -it -u root openclaw sh
|
||
```
|
||
|
||
### 7.4 文件权限修复
|
||
|
||
```bash
|
||
# docker cp 后文件属主变为宿主机用户,需修复
|
||
docker exec -u root openclaw chown -R node:node /home/node/.openclaw
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 升级流程
|
||
|
||
```bash
|
||
# 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. 微信频道配置
|
||
|
||
```bash
|
||
# 扫码登录(交互式,需终端执行)
|
||
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 待办) |
|
||
|
||
---
|
||
|
||
## 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:
|
||
```bash
|
||
docker run -d --name browserless --restart always \
|
||
--network openclaw-net \
|
||
-e MAX_CONCURRENT_SESSIONS=10 \
|
||
-e PREBOOT_CHROME=true \
|
||
-e PREBOOT_QUANTITY=2 \
|
||
-e KEEP_ALIVE=true \
|
||
-e CONNECTION_TIMEOUT=600000 \
|
||
browserless/chrome:latest
|
||
```
|
||
|
||
OpenClaw 端(`plugins.allow` 含 `browser`,且已应用 5.5 的 `browser` 配置):
|
||
```bash
|
||
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":["example.com","*.example.com","baidu.com","*.baidu.com","browserless","172.18.0.3"]},
|
||
{"path":"browser.ssrfPolicy.allowedHostnames","value":["example.com","*.example.com","baidu.com","*.baidu.com","browserless","172.18.0.3"]}
|
||
]'
|
||
docker restart openclaw
|
||
```
|
||
|
||
### 12.3 三层验证
|
||
|
||
**第 1 层:网络/CDP 协议可用性(openclaw 容器内执行)**
|
||
```bash
|
||
# 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 闭环**
|
||
```bash
|
||
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 层:稳定性(连续独立调用)**
|
||
```bash
|
||
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` + `PREBOOT/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 待办 |
|
||
|
||
### 12.5 Browserless 容器常用运维
|
||
|
||
```bash
|
||
# 查看 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 命令
|
||
```
|
||
|
||
---
|
||
|
||
## 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:
|
||
|
||
```bash
|
||
# 方式 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 文件后:
|
||
|
||
```bash
|
||
# 本地改完先 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 首次启动后必做的事
|
||
|
||
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.md` 与 `insights.md`。
|
||
|
||
### 13.6 Browserless 重建(启用持久化登录态 + Stealth)
|
||
|
||
为让四大平台(小红书 / 抖音 / 淘宝 / LinkedIn 等)登录态长期保留,需重建 browserless:
|
||
|
||
```bash
|
||
# 停止旧容器
|
||
docker stop browserless && docker rm browserless
|
||
|
||
# 创建持久化 profile 目录(NAS 宿主机)
|
||
sudo mkdir -p /volume1/docker/browserless-profile
|
||
sudo chown -R 1000:1000 /volume1/docker/browserless-profile
|
||
|
||
# 重建(带 stealth + 持久化 profile)
|
||
docker run -d --name browserless --restart always \
|
||
--network openclaw-net \
|
||
-v /volume1/docker/browserless-profile:/profile \
|
||
-e MAX_CONCURRENT_SESSIONS=10 \
|
||
-e PREBOOT_CHROME=true \
|
||
-e PREBOOT_QUANTITY=2 \
|
||
-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
|
||
|
||
把所有目标平台域名一次写入(**整体覆盖**,务必带齐旧值):
|
||
|
||
```bash
|
||
docker exec openclaw node dist/index.js config set --batch-json '[
|
||
{"path":"browser.ssrfPolicy.hostnameAllowlist","value":[
|
||
"example.com","*.example.com",
|
||
"baidu.com","*.baidu.com","tieba.baidu.com","baijiahao.baidu.com","haokan.baidu.com","b2b.baidu.com",
|
||
"browserless","172.18.0.3",
|
||
"mp.weixin.qq.com","weixin.qq.com","channels.weixin.qq.com",
|
||
"zhihu.com","*.zhihu.com",
|
||
"xiaohongshu.com","*.xiaohongshu.com",
|
||
"bilibili.com","*.bilibili.com",
|
||
"csdn.net","*.csdn.net",
|
||
"cnblogs.com","*.cnblogs.com",
|
||
"sohu.com","*.sohu.com",
|
||
"douyin.com","*.douyin.com","creator.douyin.com",
|
||
"kuaishou.com","*.kuaishou.com","cp.kuaishou.com",
|
||
"gongkong.com","*.gongkong.com",
|
||
"chem17.com","*.chem17.com",
|
||
"made-in-china.com","*.made-in-china.com",
|
||
"linkedin.com","*.linkedin.com",
|
||
"facebook.com","*.facebook.com",
|
||
"web.whatsapp.com",
|
||
"taobao.com","*.taobao.com","tmall.com","*.tmall.com","2.taobao.com",
|
||
"goofish.com","*.goofish.com"
|
||
]},
|
||
{"path":"browser.ssrfPolicy.allowedHostnames","value":[
|
||
"example.com","*.example.com",
|
||
"baidu.com","*.baidu.com","tieba.baidu.com","baijiahao.baidu.com","haokan.baidu.com","b2b.baidu.com",
|
||
"browserless","172.18.0.3",
|
||
"mp.weixin.qq.com","weixin.qq.com","channels.weixin.qq.com",
|
||
"zhihu.com","*.zhihu.com",
|
||
"xiaohongshu.com","*.xiaohongshu.com",
|
||
"bilibili.com","*.bilibili.com",
|
||
"csdn.net","*.csdn.net",
|
||
"cnblogs.com","*.cnblogs.com",
|
||
"sohu.com","*.sohu.com",
|
||
"douyin.com","*.douyin.com","creator.douyin.com",
|
||
"kuaishou.com","*.kuaishou.com","cp.kuaishou.com",
|
||
"gongkong.com","*.gongkong.com",
|
||
"chem17.com","*.chem17.com",
|
||
"made-in-china.com","*.made-in-china.com",
|
||
"linkedin.com","*.linkedin.com",
|
||
"facebook.com","*.facebook.com",
|
||
"web.whatsapp.com",
|
||
"taobao.com","*.taobao.com","tmall.com","*.tmall.com","2.taobao.com",
|
||
"goofish.com","*.goofish.com"
|
||
]}
|
||
]'
|
||
docker restart openclaw
|
||
```
|
||
|
||
### 13.8 把 `browser` 工具曝露给默认 Agent
|
||
|
||
当前 `tools.profile=coding` 不含 browser(见 §10.4 待办)。可切换到通用 profile:
|
||
|
||
```bash
|
||
# 方案 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` 的心跳任务
|
||
|