運用

バックアップと災害復旧

何をバックアップし、どのように復元し、障害にどう備えるか。

対応エディション

ObjectOS 自体はステートレスです。ランタイムはコンテナイメージから再構築できます。バックアップの対象は、ObjectOS 自体ではなく、ObjectOS が依存するデータです。 復旧はそれらのデータセットを中心に計画してください。このページの内容はすべて、Community にも Enterprise にも当てはまります。

バックアップするもの

資産所有者バックアップ戦略
業務データベース顧客データベースネイティブのバックアップ(マネージドサービスでは PITR)。四半期ごとに復元をテスト
コンパイル済みアーティファクト(objectstack.json)アプリケーション/リリースチーム公開したすべてのアーティファクトを不変のストレージに保存し、決して上書きしない
シークレットの基準値。何よりも OS_SECRET_KEY顧客のシークレットマネージャー値そのものを預託する。ローテーションの頻度はポリシーに従う
オブジェクト/ファイルストレージ(storage 機能が有効な場合)顧客バケットのバージョニング + 必要に応じてリージョン間レプリケーション
ローカルストレージ上のアップロードされたファイル(OS_STORAGE_LOCAL_ROOT)顧客データベースと同じスケジュールで。レコードとその添付ファイルが同じ時点に復元されるように
顧客管理のアイデンティティプロバイダーIdP ベンダーベンダーネイティブ

OS_SECRET_KEY のないデータベースバックアップは不完全なバックアップです。 保存されたすべてのシークレット(暗号化された設定、secret フィールド、データソースの認証情報)は、その 1 つのキーで暗号化されています。元のキーなしで復元したデータベースは、それらの値を読めないまま永久に保持することになります。キーは生成したその日に預託し、キーとデータベースをひとつのバックアップ単位として扱ってください。

OS_DATABASE_URL と OS_SECRET_KEY を設定したコンテナは、自身のファイルシステムをバックアップする必要がありません。キャッシュは再構築できます。キャッシュされたアーティファクトは読み取りのたびに完全性の固定に照らして再検証されるため、キャッシュを失っても取得が 1 回増えるだけで、正しさが損なわれることはありません。デフォルト設定で動作する単一ホストは事情が異なります。そのホームディレクトリには SQLite データベース、アップロードされたファイル、自己生成したシークレットキーがあるため、ファイルのバックアップに含めてください。

データベースのバックアップ

戦略はドライバーに合わせます。

ドライバー推奨される方法
PostgreSQL継続的な WAL アーカイブ + ベースバックアップ。ポイントインタイムリストア。小さなデータベースでは、pg_dump --format=custom も実用的な論理バックアップです
MySQLバイナリログのアーカイブ + フルダンプ。ポイントインタイムリストア
MongoDBレプリカセットのスナップショット。PITR には oplog
SQLite(シングルノード / デスクトップ)WAL モード + VACUUM INTO または Online Backup API によるホットスナップショット。任意で継続的なレプリケーションに Litestream。後述の SQLite のデプロイメントを参照

ドライバーにかかわらず、次のことを検証してください。

  • バックアップが顧客の RPO 内に完了する
  • 新しいデータベースで、同じアーティファクトから ObjectOS を起動し、トラフィックを提供できる
  • 復元テストを少なくとも四半期に一度、エンドツーエンドで実施する

SQLite のデプロイメント

SQLite はデフォルトのドライバーであり、シングルノードの ObjectOS(デスクトップアプリ、小規模チームの社内ツール、エッジ / オンプレミスのアプライアンス、評価環境)にとって正当な本番の選択肢です。トレードオフは構造的なものです。SQLite は単一ライターなので、マルチノードの ObjectOS、高い同時書き込みスループット、共有データベースのデプロイメントには適しません。それらには PostgreSQL を使ってください。

本番で SQLite を実行する場合は、安全にするための設定とバックアップの手順をセットで考えます。

ランタイムの設定

  • ランタイムはファイルベースの SQLite を WAL モードで保持します(読み取りが書き込みをブロックせず、クラッシュに対して安全)。つまり、データベースの横にある app.db-wal には、まだ app.db に入っていないコミット済みの書き込みが含まれることがあります。ランタイムの実行中に app.db だけをコピーしないでください。
  • PRAGMA synchronous=NORMAL は、デスクトップ/シングルノードの通常のデフォルトです。WAL と組み合わせれば安全で、FULL よりはるかに高速です。
  • データベースファイルはローカルディスクに置いてください。ランタイムの実行中に、NFS、SMB、または Dropbox / OneDrive / iCloud で同期されるフォルダーの中に置かないでください。それらでは SQLite のロックが信頼できず、SQLite のデプロイメントが破損する最も一般的な原因です。

ホットスナップショット(ダウンタイムなし)

SQLite の Online Backup API または VACUUM INTO でスナップショットを取る間も、ランタイムはトラフィックを提供し続けます。

VACUUM INTO '/var/backups/objectos/db-2026-05-27T13-00Z.sqlite';

RPO に合った頻度でスケジュールします(cron、systemd タイマー、またはプロセス内のスケジューラー)。各スナップショットには、それを生成したアーティファクトのバージョンをタグ付けし、データベースとアーティファクトを一緒にロールバックできるようにします(後述のアーティファクトのバージョン管理を参照)。

オフサイトのコピー

ローカルのスナップショットはディスクの喪失を乗り越えられません。各スナップショットを耐久性のあるストレージに送ります。

  • サーバー / VM:S3 または S3 互換のバケットに送ります(storage 機能のためにすでに設定しているものがあるはずです)。
  • デスクトップアプリ:ユーザーが管理する同期フォルダー(OneDrive / iCloud / Google Drive)にスナップショットを書き込みます。稼働中のデータベースと違い、スナップショットファイルは閉じていて不変なので、ここでは問題ありません。

継続的なレプリケーション(より低い RPO)

SQLite のまま 1 分未満の RPO を実現するには、ObjectOS のプロセスと並べて Litestream を実行します。WAL を S3 互換のストレージにストリーミングし、ポイントインタイムリストアをサポートします。シングルノードの SQLite デプロイメントでデータ損失をほぼゼロにする必要がある場合の推奨される方法です。

復元

ランタイムを停止し、データベースファイルを選んだスナップショットで置き換え(または litestream restore を実行し)、古い -wal や -shm ファイルが横に残っていないことを確認してから、スナップショットを生成したのと同じアーティファクトのバージョンでランタイムを起動します。

アーティファクトのバージョン管理

公開したアーティファクトは不変として扱います。各アーティファクトには、コンパイルに使ったリリース id をタグ付けします(例:objectstack-2026-05-24.json)。正常だとわかっている業務の状態への復旧は、通常次のようになります。

  1. データベースを選んだ時点に復元します。
  2. ObjectOS を、その時点で稼働していたアーティファクトのバージョンに向け直します。
  3. ランタイムを再起動します。

アーティファクトをその場で上書きすると、データベースのバックアップが完璧でも、きれいにロールバックする能力を失います。

RPO/RTO の計画

顧客のデプロイメントで実用的な最初の目標:

区分RPORTO備考
評価 / デモベストエフォートベストエフォートSQLite のスナップショットで十分
デスクトップアプリ / 小規模チームのシングルノード1 時間以内(スナップショット)または数秒以内(Litestream)数分SQLite + WAL + スケジュールされた VACUUM INTO + オフサイトのコピー
シングルテナントの本番15 分以内1 時間以内PITR 付きのマネージド PostgreSQL + ウォームイメージ
マルチテナント / 規制対象5 分以内30 分以内HA データベース + マルチ AZ の ObjectOS + テスト済みのランブック

より厳しい目標には、ObjectOS のコンテナ自体の外にあるプラットフォームの変更(HA データベース、マルチ AZ のイングレス、ウォームレプリカ)が必要です。

予行演習すべき障害モード

  • データベースが長時間利用できない。 ObjectStack 17.0 以降、これは期待するものではなく契約上の動作です。データドライバーが応答しない間、/api/v1/ready は 503 を返すため、readiness プローブは Pod を準備未完了とマークします。復旧を予行演習してください。データベースが戻ればレプリカが再参加すること、そしてそれに気づくために何も再起動を必要としないことです。オブジェクトがバインドするデータソースで、起動時に接続できないものは起動を失敗させるようになったため、アプリケーションのレプリカがロールする前に復元が完了することを確認してください。
  • アーティファクトの不具合。 アーティファクトのポインターをロールバックします。データには影響しません。
  • シークレットのローテーション。 OS_AUTH_SECRET をローテーションすると、すべてのセッションが無効になります。メンテナンスウィンドウ中に実施するか、レプリカごとに時間をずらして実施してください。
  • リージョンの障害。 顧客がリージョンのフェイルオーバーを求める場合、業務データベース、シークレットマネージャー、イングレスのすべてがリージョンをまたぐ必要があります。ObjectOS 自体は、イメージが利用できる場所ならどこでも実行できます。

復元の予行演習

本番稼働の前に一時的なホストでこれを予行演習し、ストレージを変更した後にもう一度行ってください。復元したことのないバックアップは、バックアップではなく希望にすぎません。

  1. バックアップを取得したときと同じイメージのバージョンで、クリーンなホストを用意します。

  2. データベースを復元します。プロバイダーのスナップショットを使うか、次のようにします。

    pg_restore --clean --if-exists -d "$OS_DATABASE_URL" backup-2026-07-14.dump
  3. 元のシークレットを用意します。 OS_SECRET_KEY と OS_AUTH_SECRET は預託した元の値であり、新たに生成した値であってはなりません。ローカルストレージを使っている場合は、アップロードされたファイルも復元します。

  4. 同じアーティファクトのバージョンで起動し、検証します。

    curl -fsS https://app.example.com/api/v1/health
    curl -fsS https://app.example.com/api/v1/ready

    次に、復元をエンドツーエンドで証明します。実際のアカウントでサインインし、バックアップ前から存在したレコードを開き、暗号化された設定から値を読み取ります。これが OS_SECRET_KEY を検証する操作です。

ランブックに記載すべきこと

  • 各データセットのバックアップのスケジュール、保持期間、オンコールの連絡先。
  • ステップごとの復元手順(まずデータベース、次にアーティファクト、そして ObjectOS の起動)。
  • 復元したデータベースの整合性を確認する検証クエリ。
  • ObjectOS のイメージとアーティファクトのバージョンの両方のロールバック計画(アップグレードとロールバックを参照)。
  • 顧客に見えるインシデントのための連絡テンプレート。

Enterprise で追加されるもの

  • 以前のイメージのダイジェストをバックアップと一緒に保管します。 ある時点への復元は、その時点で稼働していたダイジェストへの復元です。エアギャップのサイトでは、以前のダイジェストが唯一のコピーかもしれません。エアギャップを参照してください。
  • OS_LICENSE_KEY はシークレットの基準値に含めます。 復元したデプロイメントは与えられたライセンスで起動し、マルチ組織の姿勢ではライセンスがないと起動を拒否します。
  • レプリカがロールする前に復元します。 バンドルのスタックは、どのレプリカよりも先に 1 回限りのマイグレーションを実行するため、スタックが起動する時点でデータベースが完全でなければなりません。