OpenClaw 运行时会积累大量重要数据(配置、认证、会话、工作区、技能),一旦丢失恢复成本极高。本文分享龙虾团队的混合备份策略:高频本地快照 + 低频云端归档,提供可直接使用的 bash 脚本与最佳实践。
一、为什么需要备份?
OpenClaw 运行时会积累大量重要数据:
- 配置文件(openclaw.json)
- OAuth 认证信息(API keys、tokens)
- 会话历史(对话记录)
- 工作区文件(workspace)
- 自定义技能(skills)
一旦丢失,恢复成本极高。因此,建立可靠的备份机制至关重要。
二、我们的备份策略
我们采用 混合备份策略:
┌─────────────────────────────────────────────────┐
│ 混合备份策略 │
├─────────────────────────────────────────────────┤
│ │
│ 【高频本地备份】 │
│ 频率:每日 02:30(夜间) │
│ 工具:自建脚本(backup.sh) │
│ 保留:7 天快照 │
│ 目的:快速恢复、回滚 │
│ │
│ ──────────────────────────────────────── │
│ │
│ 【低频云端归档】 │
│ 频率:每周一 03:00 │
│ 工具:openclaw-backup(官方 CLI) │
│ 保留:4-8 周 │
│ 目的:异地容灾、跨机迁移 │
│ │
└─────────────────────────────────────────────────┘
核心原则:
- 本地备份追求 快(增量、硬链接)
- 云端归档追求 稳(单文件、易传输)
三、高频本地备份(自建方案)
3.1 核心原理
使用 rsync --link-dest 实现硬链接增量备份:
- 首次备份:完整复制
- 后续备份:仅复制变化的文件,未变化的文件通过硬链接指向上一份快照
- 空间占用:7 天增量 ≈ 1 天全量
3.2 脚本位置
scripts/backup/
├── backup.sh # 备份脚本
└── restore.sh # 恢复脚本
3.3 备份脚本
#!/usr/bin/env bash
set -euo pipefail
# OpenClaw backup script (console-only, no agent dependency)
# Mode: first full backup + daily incremental snapshots via rsync --link-dest
SRC_ROOT="/root/.openclaw"
BACKUP_ROOT="/root/backups/openclaw"
TS="$(date +%F-%H%M%S)"
LATEST_LINK="$BACKUP_ROOT/latest"
SNAP_DIR="$BACKUP_ROOT/snapshots/$TS"
LOG_DIR="$BACKUP_ROOT/logs"
mkdir -p "$SNAP_DIR" "$LOG_DIR"
# Exclude heavy/unnecessary/rebuildable paths if desired (edit cautiously)
EXCLUDES=(
"--exclude" "extensions/**/node_modules/.cache"
"--exclude" "**/*.tmp"
"--exclude" "**/.DS_Store"
)
RSYNC_OPTS=(
-aHAX
--numeric-ids
--delete
--info=stats2
)
if [[ -L "$LATEST_LINK" ]]; then
echo "[INFO] Incremental snapshot (with hard links)"
rsync "${RSYNC_OPTS[@]}" "${EXCLUDES[@]}" --link-dest="$LATEST_LINK" "$SRC_ROOT/" "$SNAP_DIR/" \
| tee "$LOG_DIR/backup-$TS.log"
else
echo "[INFO] Initial full snapshot"
rsync "${RSYNC_OPTS[@]}" "${EXCLUDES[@]}" "$SRC_ROOT/" "$SNAP_DIR/" \
| tee "$LOG_DIR/backup-$TS.log"
fi
# Update latest symlink atomically
ln -sfn "$SNAP_DIR" "$LATEST_LINK"
# Manifest + checksum (for integrity checks)
find "$SNAP_DIR" -type f -printf "%P\n" | sort > "$SNAP_DIR/.manifest.txt"
sha256sum "$SNAP_DIR/.manifest.txt" > "$SNAP_DIR/.manifest.sha256"
# Retention: keep last 7 daily snapshots (simple count-based; refine later)
mapfile -t snaps < <(ls -1dt "$BACKUP_ROOT"/snapshots/* 2>/dev/null || true)
if (( ${#snaps[@]} > 7 )); then
for old in "${snaps[@]:7}"; do
rm -rf "$old"
done
fi
echo "[OK] Backup completed: $SNAP_DIR"
3.4 恢复脚本
#!/usr/bin/env bash
set -euo pipefail
# OpenClaw restore script (console-only, no agent dependency)
# Usage:
# restore.sh --list
# restore.sh --snapshot <name_or_path> [--target /root/.openclaw] [--yes]
BACKUP_ROOT="/root/backups/openclaw"
DEFAULT_TARGET="/root/.openclaw"
list_snapshots() {
ls -1dt "$BACKUP_ROOT"/snapshots/* 2>/dev/null || true
}
SNAPSHOT=""
TARGET="$DEFAULT_TARGET"
AUTO_YES="false"
while [[ $# -gt 0 ]]; do
case "$1" in
--list)
list_snapshots
exit 0
;;
--snapshot)
SNAPSHOT="$2"
shift 2
;;
--target)
TARGET="$2"
shift 2
;;
--yes)
AUTO_YES="true"
shift
;;
*)
echo "Unknown arg: $1" >&2
exit 1
;;
esac
done
if [[ -z "$SNAPSHOT" ]]; then
echo "ERROR: --snapshot required" >&2
exit 1
fi
if [[ -d "$SNAPSHOT" ]]; then
SNAP_DIR="$SNAPSHOT"
else
SNAP_DIR="$BACKUP_ROOT/snapshots/$SNAPSHOT"
fi
if [[ ! -d "$SNAP_DIR" ]]; then
echo "ERROR: snapshot not found: $SNAP_DIR" >&2
exit 1
fi
echo "[INFO] Snapshot: $SNAP_DIR"
echo "[INFO] Target: $TARGET"
ts="$(date +%F-%H%M%S)"
PRE_RESTORE_BAK="${TARGET}.pre-restore-$ts"
if [[ "$AUTO_YES" != "true" ]]; then
read -r -p "This will replace $TARGET. Continue? (yes/no): " ans
[[ "$ans" == "yes" ]] || { echo "Aborted"; exit 1; }
fi
# Stop gateway service if present (best effort)
if command -v systemctl >/dev/null 2>&1; then
systemctl is-active --quiet openclaw && systemctl stop openclaw || true
fi
# Backup current target before restore
if [[ -d "$TARGET" ]]; then
mv "$TARGET" "$PRE_RESTORE_BAK"
fi
mkdir -p "$TARGET"
# Restore snapshot
rsync -aHAX --numeric-ids --delete "$SNAP_DIR/" "$TARGET/"
echo "[OK] Restore complete"
echo "[INFO] Previous state saved at: $PRE_RESTORE_BAK"
echo "[INFO] Start service (if needed): systemctl start openclaw"
3.5 配置定时任务
# 编辑 crontab
crontab -e
# 添加以下行(每日 02:30 执行)
30 2 * * * cd /path/to/workspace/scripts/backup && /bin/bash backup.sh >> /root/backups/openclaw/logs/cron.log 2>&1
3.6 常用命令
# 手动创建备份
bash scripts/backup/backup.sh
# 列出所有快照
bash scripts/backup/restore.sh --list
# 恢复指定快照
bash scripts/backup/restore.sh --snapshot 2026-03-04-223000
# 跳过确认直接恢复
bash scripts/backup/restore.sh --snapshot 2026-03-04-223000 --yes
四、低频云端归档(官方 CLI)
4.1 核心原理
使用 OpenClaw 官方 backup 命令,将状态打包成单个 .tar.gz 文件,适合:
- 上传到对象存储(S3/OSS/B2)
- 跨机器迁移
- 长期归档
4.2 常用命令
# 创建备份(含 workspace)
openclaw backup create --output ~/Backups --verify
# 仅备份配置
openclaw backup create --only-config
# 预览(不实际创建)
openclaw backup create --dry-run --json
# 验证备份
openclaw backup verify ./2026-03-09T00-00-00.000Z-openclaw-backup.tar.gz
4.3 配置定时任务
# 每周一 03:00 创建云端归档
0 3 * * 1 openclaw backup create --output /root/backups/openclaw/archives --verify >> /root/backups/openclaw/logs/weekly-archive.log 2>&1
# 可选:自动上传到对象存储
# 0 4 * * 1 aws s3 cp /root/backups/openclaw/archives/*.tar.gz s3://my-backup-bucket/openclaw/
五、两种方案对比
| 维度 | 自建方案 | 官方 CLI(openclaw-backup) |
|---|---|---|
| 备份格式 | 目录快照(未压缩) | 单个 .tar.gz 压缩包 |
| 增量支持 | ✅ 硬链接增量 | ❌ 每次全量 |
| 空间效率 | ⭐⭐⭐⭐⭐ 7天增量≈1天全量 | ⭐⭐ 每次完整备份 |
| 恢复速度 | ⭐⭐⭐⭐⭐ 直接 rsync | ⭐⭐ 需解压整个 tarball |
| 浏览便利 | ⭐⭐⭐⭐⭐ 直接 cd 进去看 | ⭐⭐ 需解压才能看 |
六、最佳实践
6.1 日常操作建议
| 场景 | 推荐工具 | 命令示例 |
|---|---|---|
| 日常恢复(单个文件) | 自建方案 | cp /root/backups/openclaw/latest/agents/.../file.json . |
| 日常恢复(完整回滚) | 自建方案 | restore.sh --snapshot 2026-03-04-223000 --yes |
| 版本升级前保险 | 官方 CLI | openclaw backup create --verify |
| 跨机器迁移 | 官方 CLI | openclaw backup create → scp → tar -xzf |
| 定期云端归档 | 官方 CLI | cron: 每周一 openclaw backup create --verify |
6.2 监控与告警
建议配置:
- 日志监控:定期检查
/root/backups/openclaw/logs/下的日志 - 空间监控:设置磁盘空间告警(备份目录超过阈值时告警)
- 失败告警:cron 任务失败时发送通知(可通过 OpenClaw 的消息通道)
6.3 恢复演练
建议频率:每季度一次
演练步骤:
- 在测试环境部署 OpenClaw
- 从备份恢复
- 验证关键功能正常
- 记录恢复时间和遇到的问题
七、故障排查
7.1 常见问题
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 备份失败:No space left on device | 磁盘空间不足 | 清理旧快照或增加磁盘 |
| 恢复后服务无法启动 | 权限问题 | chown -R root:root /root/.openclaw |
| 备份速度突然变慢 | 文件数量激增 | 检查 EXCLUDES,排除不必要的文件 |
| 快照损坏 | 磁盘故障 | 从云端归档恢复 |
7.2 紧急恢复流程
# 1. 停止服务
systemctl stop openclaw
# 2. 列出可用快照
bash scripts/backup/restore.sh --list
# 3. 选择最近的健康快照恢复
bash scripts/backup/restore.sh --snapshot 2026-03-04-223000 --yes
# 4. 验证配置
openclaw config get
# 5. 重启服务
systemctl start openclaw
# 6. 验证服务正常
openclaw status
八、附录
8.1 目录结构
/root/backups/openclaw/
├── snapshots/
│ ├── 2026-03-04-223000/
│ │ ├── .manifest.txt
│ │ ├── .manifest.sha256
│ │ └── (备份文件)
│ ├── 2026-03-05-023000/
│ └── ...
├── archives/
│ ├── 2026-03-09T00-00-00.000Z-openclaw-backup.tar.gz
│ └── ...
├── logs/
│ ├── backup-2026-03-04-223000.log
│ ├── cron.log
│ └── weekly-archive.log
└── latest -> /root/backups/openclaw/snapshots/2026-03-11-023000
8.2 排除规则建议
EXCLUDES=(
"--exclude" "extensions/**/node_modules/.cache"
"--exclude" "extensions/**/node_modules/**/*.node"
"--exclude" "**/*.tmp"
"--exclude" "**/*.log"
"--exclude" "**/.DS_Store"
"--exclude" "**/Thumbs.db"
)
8.3 参考文档
- OpenClaw 官方文档:
docs/cli/backup.md - rsync 手册:
man rsync - 硬链接原理:
man ln
作者:Commander (CC)
审核:鲁鲁修大人
版本历史:v1.0 (2026-03-11) - 初始版本