コンテンツにスキップ

管理画面から園全体を復元する

管理者が「設定 → バックアップ・復元 → 復元元を選ぶ」を開き、保存日時と理由を選ぶ。事前検査の後、戻る内容を確認し、確認チェックと現在の管理者パスワードで実行する。実行前は選び直し・取消ができる。実行後は画面を閉じても処理が継続する。

対象は主DB・施設文例DB・写真・添付・DB内設定。選んだ日時以降の変更は戻る。アカウント・パスワードもその日時へ戻るが、現在の管理者が同じパスワードで再ログインできることを開始前に確認する。サーバー接続設定や秘密鍵は現行値を使う。

復元中は職員・保護者の画面を利用停止にする。直前の状態を追加で退避してから、別領域で復元データを検査し、起動確認後に利用を再開する。切替後の失敗は直前の退避へ戻す。自動復旧に失敗したら利用停止を継続するため、画面に出る作業番号を運用担当者へ伝える。

復元後は全員が再ログインする。古いログイン・再設定・登録用トークンを失効させ、過去の送信待ち通知を取り消す。形式2は保存された頻度・時刻を戻し、定期バックアップを無効にする。形式1は現在の頻度・時刻を維持して無効にする。管理者が設定を確認して再開する。作業履歴から進行状況を再表示できる。

対応するバックアップ

main統合版は形式1・形式2のうち、明示したアプリ版・同じ園・現在と互換のあるDBスキーマに対応する。形式2は保存時のスキーマ契約と検証記録も検査する。家庭アーカイブ追加前のDBは準備用コピーだけを更新し、元のバックアップを維持する。復元直前の退避は形式2で作成し、イメージの固定digest・復旧手順の記録ID・復元ジョブIDを記録する。選択時にハッシュ・DB・外部キー・添付・写真を再検査する。対象外の版や形式、欠損・不整合、管理者が再ログインできない復元元は画面から実行できない。外部ファイルのアップロードと部分復元は対象外。

配備と保守

deploy/truenas/restore.compose.yaml の追加設定を現在のComposeへマージする。Webの固定入口はapp:8000を維持し、gatewayが子アプリ127.0.0.1:8001の停止・起動とHTTP/WebSocket中継を担当する。ネットワークを持たない非rootのrestore-workerがDBと添付を切り替える。どのサービスにもDockerソケットやホスト管理権限を渡さない。

復元制御・履歴、準備領域、バックアップ、32バイトの署名鍵はruntimeデータセットの外に置く。ファイルとディレクトリはアプリUIDが必要な範囲だけアクセスできるようにする。appはバックアップを読み取り専用でマウントする。秘密鍵の中身はログや更新記録に出さない。

更新・手動復旧時は復元のactive.jsonとmaintenance.jsonを確認し、復元中・自動復旧失敗中は通常配備を中止する。backup-worker・restore-worker・appを停止してからデータを扱う。新しいコードだけで古いスキーマを許可しない。対応版一覧を更新する前に隔離コピーで互換性を検証する。

署名済み依頼・期限付き事前確認・同時実行ロック・アプリ停止とbackup-worker停止の応答を使う。適用前に耐久化した履歴を保存し、再起動時に切り戻す。利用再開前には切替確定を先に保存し、新たな業務入力を後から巻き戻さない。アプリ全体が起動できない障害ではサーバー側の復旧経路を使う。

検証

python -m pytest -q test_restore_runtime.py は架空DB・添付で成功、破損、互換性、二重実行、途中失敗、切り戻し失敗、再起動を検査する。python -m scripts.verify_restore_runtime は実アプリ子プロセスと専用workerを起動して、ログイン・CSRF・パスワード再確認・WebSocket・利用停止・復元・再ログインを通す。後者は使われていないポート8001、または --network none の使い捨てコンテナで実行する。本番DBや本番への復元依頼は使わない。

9月22日時点の本番配備は引き続き形式1。mainへの統合だけでは本番・デモの稼働環境は更新されない。