mcpField
O
openclaw-backup

openclaw-backup

github.com/bhagyamudgalクラウド・DevOps298 回インストール3 日前に更新
リポジトリ

openclaw-backup について

openclaw-backupは、現在のマシンまたは指定ホスト上のOpenClawをバックアップするスキルです。状態データ、データベース、アーカイブ、メタデータを段階的に検証し、証拠と復元手順を記録します。

主な機能

  1. 01OpenClawの状態ディレクトリとDBを検出
  2. 02SQLite DBをスナップショットして検証
  3. 03公式アーカイブと raw アーカイブを作成
  4. 04外部ワークスペースを個別に保存
  5. 05サービス情報を収集しチェックサム一覧を生成
  6. 06任意の別ホストコピーとチェックサム検証

活用シーン

  1. 01現在のマシン上のOpenClawをバックアップ
  2. 02SSH経由でリモートホストをバックアップ
  3. 03アーカイブに会話履歴が含まれるか確認
  4. 04別ホストコピーのアクセス制御とチェックサムを検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bhagyamudgal/skills --skill openclaw-backup

インストール後、Claude Code で/openclaw-backupを入力して読み込まれたか確認します。

同梱ファイルreferences/restore-template.mdreferences/sqlite-snapshot.md

詳細

各ステップの最後にはゲートがあります。ゲートとは、証拠を生成するチェックです。実行しなかったゲートは、失敗したゲートです。このスキルが対処する失敗は、気付きにくいものです。アーカイブの作成と検証は問題なく完了するのに、必要なものが入っていないことがあります。

入力

  • なし。現在のマシンにインストールされている OpenClaw をバックアップします。
  • ホスト。user@host を渡し、すべてのコマンドの前に SSH の呼び出しを付けます。それ以外の手順は同じです。

可能な情報は自動で検出します。尋ねるのはバックアップ先だけです。既定値は ~/backups/<date>-preflight です。また、コピーをマシン外に転送するかどうかも尋ねます。

ステップ 0:事前確認

STATE_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
[ -d "$STATE_DIR" ] || { echo "FAIL: no OpenClaw state dir at $STATE_DIR"; exit 1; }

openclaw --version
node --version                      # v22+ carries node:sqlite, needed in Step 3
du -sh "$STATE_DIR"
df -h "$STATE_DIR"
find "$STATE_DIR" -name '*.sqlite' -not -path '*/node_modules/*' | sort

実行のたびに find を使ってデータベースを検出します。OpenClaw はバージョンによってデータベースの場所を変更します。2026.7 では、メモリデータベースが memory/main.sqlite から agents/<id>/agent/openclaw-agent.sqlite に移動しました。そのため、パスをハードコードすると何も見つからないままになります。

ワークスペースを特定します。ワークスペースは状態ディレクトリの外にある場合があります。設定内の OPENCLAW_WORKSPACE_DIR と agents.defaults.workspace を確認します。ワークスペースが状態ディレクトリの外にある場合は、別のアーカイブソースです。パスを WORKSPACE_DIR として記録します。状態ディレクトリ内にあり、未加工のアーカイブですでにカバーされている場合は、空にします。

ホストを調べて、ゲートウェイの実行方法を特定します。openclaw-gateway.service などの systemd ユーザーユニット、システムユニット、pm2、Docker、launchd のいずれかです。ユーザーユニットでは、すべてのコマンドで systemctl --user が必要です。通常の systemctl では「unit not found」と表示されます。これはサービスが停止しているように見えますが、実際には書き込みが続いています。

空き容量が状態ディレクトリの 2 倍以上あり、データベースの一覧が空でない場合にのみ、このステップを合格とします。

ステップ 1:--help から機能を確認

openclaw backup --help
openclaw backup create --help

このインストール環境では、--help の内容が信頼できる情報源です。docs.openclaw.ai には backup sqlite サブコマンドが記載されていますが、リリース済みビルドには含まれていない場合があります。そのため、ドキュメントサイトには、バイナリにない機能が記載されていることがあります。

サブコマンドの一覧を記録した場合にのみ、このステップを合格とします。sqlite がある場合は、ステップ 3 よりもそちらを優先し、その旨をレポートに記載します。

ステップ 2:停止時間のモードを選択

ユーザーに尋ねます。既定では停止時間なしを選択します。ステップ 3 ではデータベースをトランザクション方式でスナップショットします。ライブコピーに耐えられないのはデータベースだけです。

モードコスト
停止時間なし(既定)tar の実行中に書き換えられたファイルは、未加工のアーカイブ内で不完全になる場合があります。データベースは別途カバーされます。
短時間停止数分間の停止が発生し、その間のメッセージは失われます。すべての成果物が静止した状態になります。

稼働中のゲートウェイを停止する直前に、ホスト、サービスマネージャーとその名前、停止および再起動の操作、予想される停止時間、現在のプロセスとヘルス状態、復旧コマンド、ユーザーによる短時間停止の承認を正確に指定して preflight-mutations を呼び出します。サービスを停止する前に、その結果に関する契約を適用します。停止時間なしで実行する場合、このゲートは使用しません。

サービスを停止したら、アーカイブする前に pgrep -af openclaw でプロセスが終了したことを確認し、その後、正常な状態で再起動したことを確認します。

ステップ 3:すべての SQLite データベースをスナップショット

${CLAUDE_SKILL_DIR}/references/sqlite-snapshot.md を読み込み、その手順に従います。そこには VACUUM INTO スクリプトが記載されており、稼働中の WAL データベースにそれが必要な理由が説明されています。

すべてのデータベースで、ソースとスナップショットの両方の integrity_check が ok を返し、件数が N/N と表示された場合にのみ、このステップを合格とします。どちらかのチェックに失敗したデータベースがあれば、実行を中止します。対象のデータベースと表示された内容を報告します。

ステップ 4:公式アーカイブ

cd "$HOME" && openclaw backup create --verify --output "$BACKUP_DIR/official"

大規模なインストールでは数分かかります。バックグラウンドで実行し、ポーリングします。

このアーカイブでは、sessions、logs、delivery queues の下にある、稼働中に変更されるファイル(.jsonl、.log、.json、.tmp、.sock、.pid)は除外されます。セッションの記録は .jsonl であるため、次にステップ 5 を実行します。

実行の最後に Archive verification: passed が表示され、レポート用に Skipped N volatile files の件数を記録した場合にのみ、このステップを合格とします。この検証行がなければ、アーカイブは未検証として扱います。

Step 5: Raw archive:トランスクリプトを保持するもの

mkdir -p "$BACKUP_DIR/raw"
tar --use-compress-program="zstd -3 -T0" \
    --exclude='*/node_modules' \
    --warning=no-file-changed \
    -cf "$BACKUP_DIR/raw/openclaw-state-raw.tar.zst" \
    -C "$(dirname "$STATE_DIR")" "$(basename "$STATE_DIR")"
echo "EXIT=$?"

node_modules は再インストール可能であり、全体の3分の1を占めることも多いため除外します。それ以外はすべて残します。Step 4で除外した変動するファイルが、このステップの対象です。

次に、証拠を作成します。

LISTDIR=$(mktemp -d "$BACKUP_DIR/.listings-XXXXXXXX") || exit 1
zstd -t "$BACKUP_DIR/raw/openclaw-state-raw.tar.zst"
tar --use-compress-program="zstd -d" -tf "$BACKUP_DIR/raw/openclaw-state-raw.tar.zst" > "$LISTDIR/rawlist.txt"
LISTING_EXIT=$?
wc -l < "$LISTDIR/rawlist.txt"
grep -c 'sessions/.*\.jsonl' "$LISTDIR/rawlist.txt"
grep -c 'node_modules' "$LISTDIR/rawlist.txt"
rm -rf -- "$LISTDIR"

zstd -t が成功し、一覧表示の終了コードが0で、会話履歴のあるインストール環境ではセッションの .jsonl の数が0より大きく、node_modules の数が0の場合にのみ、このステップは合格です。.jsonl の数が0、または node_modules の数が0以外の場合は、除外パターンが誤っています。修正して再実行してください。tarの終了ステータスを記録します。0なら問題なく合格、1ならレポートに読み取り中の変更に関する警告を記録し、2以上ならこのステップは失敗です。

Step 5.5: Workspace archive

WORKSPACE_DIR が空の場合は、このステップをスキップします。raw archiveにすでにワークスペースが含まれています。

mkdir -p "$BACKUP_DIR/workspace"
tar --use-compress-program="zstd -3 -T0" \
    --warning=no-file-changed \
    -cf "$BACKUP_DIR/workspace/openclaw-workspace.tar.zst" \
    -C "$(dirname "$WORKSPACE_DIR")" "$(basename "$WORKSPACE_DIR")"
echo "EXIT=$?"

次に、証拠を作成します。

LISTDIR=$(mktemp -d "$BACKUP_DIR/.listings-XXXXXXXX") || exit 1
zstd -t "$BACKUP_DIR/workspace/openclaw-workspace.tar.zst"
tar --use-compress-program="zstd -d" -tf "$BACKUP_DIR/workspace/openclaw-workspace.tar.zst" > "$LISTDIR/workspacelist.txt"
LISTING_EXIT=$?
wc -l < "$LISTDIR/workspacelist.txt"
rm -rf -- "$LISTDIR"

zstd -t が成功し、一覧表示の終了コードが0で、一覧が空でない場合にのみ、このステップは合格です。tarの終了ステータスを記録します。0なら問題なく合格、1ならレポートに読み取り中の変更に関する警告を記録し、2以上ならこのステップは失敗です。

Step 6: メタデータ

以下をそれぞれ meta/ に取得します。

  • サービスユニットファイルとそのドロップインディレクトリ。オーバーライドはドロップインに保存されています。サービスマネージャーを記録します。systemdの場合は、ユニットディレクトリを UNIT_DIR として記録します。これはユニットファイルが含まれるディレクトリで、ドロップインは <name>.d の下にあります。pm2、Docker、launchdの場合、ユニットディレクトリはありません。定義ファイルをベース名を維持したまま meta/service-def/ にアーカイブし、その実際のパスを SERVICE_DEF_PATH として記録して、サービスマネージャーも記録します。テンプレートは、記録された各マネージャーに応じて復元します。
  • ユニットが参照する環境ファイル。
  • openclaw --version、node --version、グローバルnpmパッケージ。
  • リッスンしているポート、実行中のOpenClawプロセス、crontab。
  • 後の復元時にサイズを確認できるよう、各状態サブディレクトリの du -sh。

上記のすべての項目が meta/ に存在するか、理由とともにレポートに取得不能と記載されている場合にのみ、このステップは合格です。

Step 7: Manifest and RESTORE.md

cd "$BACKUP_DIR" && find . -type f ! -name MANIFEST.sha256 -print0 \
  | sort -z | xargs -0 sha256sum > MANIFEST.sha256
chmod -R go-rwx "$BACKUP_DIR"

権限の変更を適用します。これらのアーカイブには、APIトークン、メッセージングのペアリングデータ、OAuthのリフレッシュトークンが含まれています。

${CLAUDE_SKILL_DIR}/references/restore-template.md を $BACKUP_DIR/RESTORE.md にレンダリングし、Step 0で取得した実際のパス、サービス名、ユニットディレクトリ、データベース一覧に置き換えます。

MANIFEST.sha256 にすべてのアーティファクトが記載され、バックアップディレクトリのモードが 0700 で、レンダリングされた RESTORE.md に <PLACEHOLDER> トークンが残っていない場合にのみ、このステップは合格です。

ステップ 8:オフボックスコピー

保護対象と同じディスク上にあるバックアップは、設定ミスには耐えられますが、ディスクの損失には耐えられません。ユーザーが別の場所にもコピーを置きたい場合は、このステップを進めてください。

rsync の実行前に、受信側システムで、保存時の暗号化が有効であること、意図された受信者アカウントだけがアクセスできること、既知の保持期間とテスト済みの削除手順が定められていることを確認してください。最初の転送前に、宛先ホストキーが信頼できる値と一致することを確認してください。これにより、ホスト名の入力ミスや初回接続時の傍受によってコピー先が変更されるのを防げます。これらの管理策が一つでも欠けている宛先はブロックしてください。

rsync の実行直前に、確認した証拠、正確な送信元と宛先のホストおよびパス、含まれる成果物の一覧と認証情報の機密性、受信者、保持期間と削除手順、現在の宛先の状態、チェックサムとアクセス制御の読み戻し結果、およびユーザーによるオフボックスコピーの承認を添えて、preflight-mutations を実行してください。コピーの前に、その結果の契約を適用してください。

rsync -avh --partial -e ssh <source> <destination>

マニフェストと照合して、受信側で確認してください:

grep -v ' \./official/' MANIFEST.sha256 > /tmp/check.sha256   # if official/ was not pulled
sha256sum -c /tmp/check.sha256    # macOS: shasum -a 256 -c

チェックサムの出力に空でないファイル一覧が含まれていることを確認してから、合格と判断してください。空の一覧を渡された検証ツールは、何も確認していないのに成功を報告します。

チェックサムの不一致があった場合、その転送カードは使用を終了します。failed の結果と、観測された宛先の部分的な状態は、変更不可の履歴として保持してください。転送または読み戻しの状態が曖昧な場合は、reconcile-required とし、別の書き込みを計画する前に、その該当ファイルの状態を解決してください。再試行の前に、正確な送信元ファイルと宛先の部分ファイルに加え、受信側システムの暗号化、実効アクセス権、保持期間、テスト済みの削除管理策を再確認してください。不一致があったそのファイル一つと、再開可能な rsync --partial 転送一つだけを対象に、現在のガードと想定されるチェックサムの読み戻し結果を記載した新しいカードを作成してください。現在の判定が ready の場合に限り再試行し、その後の試行に進む前に、正式な結果を記録してそのカードを終了してください。

コピー後、受信側システムの暗号化と実効アクセス制御を再確認してください。どちらかが事前確認の証拠と異なる場合は、コピーを機密性のある部分的な状態として保持し、報告してください。コピーの承認は削除を許可するものではありません。正確な宛先、観測された失敗、削除アクション、削除後に存在しないことの読み戻し結果を記載した、別個の補償削除カードを作成してください。改めて明示的な確認を得て、現在の preflight 結果が ready の場合に限り削除してください。

確認対象のすべてのファイルが OK を報告し、保存時の暗号化が引き続き有効で、実効アクセスが承認済み受信者アカウントに制限され、保持期間と削除手順が引き続き利用可能な場合に限り、このステップに合格します。不一致のあるファイルについては、上記の新しいカードによる再試行の契約を通じてのみゲートを解除できます。セキュリティ管理策に失敗した場合は、機密性のある部分的な状態を保持するか、別途削除するまで完了をブロックしてください。--partial を指定すると、新しい転送を再開できます。

公式アーカイブをプルから除外するのは妥当です。その内容は生のアーカイブのサブセットです。レポートにその除外を記載してください。

ステップ 9:レポート

OPENCLAW BACKUP: <host or "local">

Install:  OpenClaw <version>, state dir <path> (<size>)
Service:  <unit/manager>, <running|stopped during backup>
Mode:     <zero-downtime | brief stop>

Artifacts (<total size>, mode 0700):
  official/<name>.tar.gz     <size>   verification: <passed|NOT VERIFIED>
  raw/<name>.tar.zst         <size>   <N> entries, <M> session transcripts
  workspace/<name>.tar.zst   <size>   <N> entries (omit when the workspace sits inside the state dir)
  sqlite/                    <size>   <X>/<X> databases, integrity ok source + snapshot
  meta/                      <size>   unit + drop-ins, env, inventory
  MANIFEST.sha256 + RESTORE.md

Official archive skipped <N> volatile files, covered by the raw archive.

VERIFIED:  <what was run, and the evidence each produced>
ASSUMED:   <what was inspected but not executed>
NOT DONE:  restore has not been rehearsed against this backup

VERDICT: <BACKUP COMPLETE | INCOMPLETE, reason>

ステップ 0~8 の「このステップに合格する条件」をすべて、証拠とともに VERIFIED に記載するか、実行しなかった理由とともに ASSUMED に記載した場合に限り、このステップに合格します。すべてが検証済みであることが BACKUP COMPLETE の条件です。

次の二つの主張は、正確な状態を保ってください:

  • チェックサムが未検証のバックアップは INCOMPLETE とします。
  • 使い捨てのターゲットに対して実際に復元を実行するまでは、復元の状態を NOT DONE のままにします。バックアップの実行で確認できるのはアーカイブが存在することまでであり、復元できることではありません。

コメント