跳转到内容

04-运维 · 03 备份与恢复

预计阅读:12 分钟 适用版本:公开稳定包 OpenClaw 2026.5.2;作者端已验证 2026.5.7 · 最后审核:2026-05-09 本章回答:哪些东西要备份?多久一次?出事了怎么恢复?什么绝对不能进备份?


核心原则:分层备份 + 白名单思维

Section titled “核心原则:分层备份 + 白名单思维”

作者踩过的坑(2026-04-17 一次严重事故):有人用”一键同步 ~/.openclaw/”打包,结果 228MB 包里含:

  • 2707 个 memory 文件(作者所有对话记忆)
  • 50 个 session JSONL(完整对话流水)
  • 4764 个误打进去的 node_modules
  • manifest.json 撒谎说”已清理”

教训:备份包是高敏感资产。“全备”=最大攻击面。

正确做法:按分层 + 按白名单。每层明确列出要备份什么,没列的就不备。


按敏感度从高到低:

层内容敏感度推荐频率
L1credentials/🔴 极高加密后一次,离线保存
L2配置(openclaw.json + agents/*/)🟡 高每日自动
L3shared 规范(shared/)🟡 中每日自动
L4Workspace 记忆(workspace/memory/、workspace/MEMORY.md)🟡 中每日自动
L5运行数据(memory/lancedb-pro/、data/graphify/)🟢 低每周一次,按需

这一层和其他层完全不同。

  1. 不进日常备份链 —— 永远不和 L2-L5 一起打包
  2. 加密后保存 —— 用 age / GPG 加密
  3. 离线 / 硬件 —— U 盘、冷钱包级硬件、密码管理器
  4. 不同步多机器 —— 每台机器重建一次,不共用
  5. 失效时先作废 —— 真丢了,先去飞书/OpenAI 后台作废旧 key,再恢复
Terminal window
# 只在重大变动时手动打包
cd ~/.openclaw
tar czf /tmp/credentials.tar.gz credentials/
age -r age1your_public_key -o ~/Documents/credentials-20260418.tar.gz.age /tmp/credentials.tar.gz
rm /tmp/credentials.tar.gz
chmod 600 ~/Documents/credentials-20260418.tar.gz.age

不用 github 即使是 private repo。github 历史是永久的,一旦 key 泄露无法彻底清除。


L2-L4:日常自动备份(推 github)

Section titled “L2-L4:日常自动备份(推 github)”

作者的做法:config、shared、workspace 三层各有独立备份脚本:

脚本范围目标
backup-config-to-github.shopenclaw.json + agents/*/你的私有 github repo
backup-shared-to-github.shshared/同上或另一个私有 repo
backup-workspace-to-github.shworkspace/memory/ + workspace/MEMORY.md同上
  • 三类变动频率不同(config 偶尔改、shared 月级、workspace memory 每天变)
  • 三类恢复粒度不同(只恢复 config 时不想带出 memory)
  • 失败隔离 —— 一个脚本挂了不影响其他两个
backup-config-to-github.sh
#!/bin/bash
set -e
BACKUP_DIR=~/.openclaw/temp/backup-config
REPO=git@github.com:<your-user>/openclaw-config-backup.git
rm -rf "$BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
# 白名单拷贝
cp ~/.openclaw/openclaw.json "$BACKUP_DIR/"
cp -r ~/.openclaw/agents/*/SOUL.md "$BACKUP_DIR/" 2>/dev/null || true
# ... 其他明确列出的文件
# 脱敏:去掉可能的敏感字段
# 注意:如果 openclaw.json 里有 inline 的 apiKey,要 jq 过滤掉
jq 'del(.auth.profiles)' "$BACKUP_DIR/openclaw.json" > "$BACKUP_DIR/openclaw.sanitized.json"
mv "$BACKUP_DIR/openclaw.sanitized.json" "$BACKUP_DIR/openclaw.json"
# commit 到私有 repo
cd "$BACKUP_DIR"
git init -q && git remote add origin "$REPO"
git add -A
git commit -q -m "backup $(date '+%Y-%m-%d %H:%M')"
git push -u -f origin HEAD:main # 强推(每次全量覆盖)
~/Library/LaunchAgents/com.openclaw.backup-config.plist
<dict>
<key>Label</key><string>com.openclaw.backup-config</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>~/.openclaw/scripts/backup-config-to-github.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict><key>Hour</key><integer>2</integer><key>Minute</key><integer>30</integer></dict>
</dict>

敏感字段脱敏清单(备份前必做)

Section titled “敏感字段脱敏清单(备份前必做)”

作者维护一份 ~/.openclaw/scripts/BACKUP_SANITIZATION_POLICY.md,核心规则:

字段处理
auth.profiles.*.apiKey删除整个 profile
auth.profiles.*.apiToken删除
channels.feishu.appSecret(如果 inline)删除
credentials/ 路径下所有文件不包含
logs/不包含
memory/lancedb-pro/ 原始文件不包含(太大 + 含敏感内容)
任何 *.secrets.json不包含
open_id(出现在 USER.md / allowFrom)保留(识别用户所需),但备份 repo 必须 private

自动校验:备份脚本结束前跑一次 grep 检查:

Terminal window
# 如果发现以下关键字,立即中止 + 告警
forbidden_keys=('apiKey' 'appSecret' 'apiToken' 'password' 'secret_key')
for key in "${forbidden_keys[@]}"; do
if grep -r "$key" "$BACKUP_DIR" 2>/dev/null; then
echo "❌ 发现敏感字段 $key,中止备份"
exit 1
fi
done

memory/lancedb-pro/ 和 data/graphify/openclaw-memory/graphify-out/ 是可重建的:

  • LanceDB 可以从 workspace/memory/ 的 .md 文件重新索引
  • Graphify 可以从 workspace/memory/ 重新跑 openclaw graphify build,产物落到 graphify-out/

策略:不高频备份,但压缩前做一份(怕压缩脚本 bug 损坏索引)。

Terminal window
# 压缩前
tar czf ~/Desktop/lancedb-snapshot-$(date +%Y%m%d).tar.gz \
~/.openclaw/memory/lancedb-pro/

没演练过的备份不叫备份。

Terminal window
# 测试机器(或你的 Mac 的测试账号)
# 完全从备份重建 ~/.openclaw/
# 1. clone 备份 repo
git clone git@github.com:<you>/openclaw-config-backup.git /tmp/restore
# 2. 放回各目录
cp /tmp/restore/openclaw.json ~/.openclaw/
cp -r /tmp/restore/agents/ ~/.openclaw/
cp -r /tmp/restore/shared/ ~/.openclaw/ # 如果在同一 repo
# 3. credentials 从离线恢复
age --decrypt -i ~/.ssh/age-key -o /tmp/credentials.tar.gz \
~/Documents/credentials-20260418.tar.gz.age
tar xzf /tmp/credentials.tar.gz -C ~/.openclaw/
# 4. 跑 doctor
openclaw doctor
# 5. 启 gateway + 冒烟
openclaw gateway start
# 按 01-入门/03-验证 的 8 维走一遍

演练要点:

  • 至少 1 次完整从头重装(不是在已有环境 mv 文件)
  • 演练时间计入 —— 知道真出事要多久恢复
  • 发现问题 → 修备份脚本 / 运维文档,不要只修这次恢复

升级 OpenClaw CLI 前,除了日常备份还要额外打一份”升级前快照”:

~/Desktop/openclaw-backup-YYYYMMDD-HHMM.tar.gz
bash ~/.openclaw/scripts/backup-memory-plugin-upgrade.sh

内容:

  • 整个 ~/.openclaw/ 的本地副本(不推 github)
  • 包含 lancedb-pro(因为升级可能破坏索引)
  • 排除 logs/(太大)

保留期:至少到下次成功升级 + 稳定 1 周后,才删。


如果你有 2+ 台机器跑 OpenClaw(主力 + 备用 / 不同业务):

  • ✅ shared/ (通过 git 同步)
  • ✅ 部分 config(公共 agent 的 SOUL,但不含 credentials)
  • ❌ credentials(每台独立,不同 appSecret)
  • ❌ memory/workspace(每台记忆独立,混在一起是灾难)
  • ❌ logs

灾难。即使脱敏脚本做了,也可能漏。备份仓库必须 private,且关闭 fork。

坑 2:脱敏只做”删除”不做”替换”

Section titled “坑 2:脱敏只做”删除”不做”替换””

删除会让 JSON 结构损坏,restore 时失败。正确是置空字符串或占位符:

{ "apiKey": "__REDACTED__" }

restore 时 agent 看到 __REDACTED__ 会报错 “key not set”,提示你手动补。比默认 crash 好。

换机器 / 换 bot 后,用户的 open_id 可能变了。恢复后要 /openid 重新获取,更新到 USER.md / allowFrom。

每 5 分钟备份一次 = git 历史爆炸 + noise 盖过真正的变动。每天 1 次足够。

坑 5:恢复演练省略 “启服务” 步骤

Section titled “坑 5:恢复演练省略 “启服务” 步骤”

只恢复了文件没启 gateway,以为”恢复成功”。真出事时发现 launchd plist 里的路径假设和新机器不一致。演练必须到”能收飞书回”才算完。


日常自动:
每日 02:30 backup-config-to-github.sh
每日 02:40 backup-shared-to-github.sh
每日 02:50 backup-workspace-to-github.sh
手动触发:
升级前 backup-memory-plugin-upgrade.sh
压缩前 L5 运行数据快照
credentials 改动时 离线加密备份
演练:
每季度 完整从备份恢复一次
每年 换机器时真跑一次

检查项怎么验
三个 backup-to-github 脚本能跑手动触发,看 github repo 是否更新
脱敏有效clone 备份 repo,grep 是否还有 apiKey/appSecret
launchd 定时已加载launchctl list | grep backup
备份大小合理github repo 总 < 100MB(超了说明含了不该含的)
恢复演练过至少一次完整重建
credentials 离线备份位置明确家人或团队能找到(如果你消失)


本章准确性保证 脚本名、目录路径、脱敏清单都基于作者 ~/.openclaw/scripts/ 的真实 BACKUP_CHAIN_RUNBOOK / BACKUP_SANITIZATION_POLICY / BACKUP_SYNC_SOP 三份运维文档(2026-04-18)。228MB 事故是 2026-04-17 真实踩坑,促成了”白名单思维”的备份原则。


导航:← 升级流程 · 📖 目录 · → 结构化状态与 State Doctor