litestream-coder について
Rails 8以降の本番環境向けにLitestreamを設定し、SQLiteをS3互換ストレージへ継続バックアップするスキルです。Kamal 2でのデプロイ、保持ポリシー、監視、災害復旧も扱います。
主な機能
- 01SQLiteからS3互換ストレージへの複製設定
- 02データベース種別ごとの同期・保持設定
- 03Kamal 2でLitestreamをデプロイ
- 04データベースと指定時点の復元
- 05複製状態の確認とVACUUM計画
活用シーン
- 01Rails本番環境のSQLiteデータを保護
- 02キャッシュ、キュー、ケーブル用DBのバックアップ設定
- 03バックアップからDBまたは指定時点を復元
- 04複製遅延の監視とVACUUMのスケジュール
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill litestream-coderインストール後、Claude Code で/litestream-coderを入力して読み込まれたか確認します。
詳細
Litestream Coder
概要
Litestream は、SQLite データベースを S3 互換ストレージに継続的にストリーミングバックアップします。Solid Queue、Solid Cache、Solid Cable を使用する、本番環境の SQLite を利用した Rails 8 以降のアプリに不可欠です。
設定ファイル
config/litestream.yml を作成します。
dbs:
- path: /rails/storage/production.sqlite3
replicas:
- type: s3
bucket: ${BUCKET_NAME}
path: sqlite/production
endpoint: ${S3_ENDPOINT}
region: ${S3_REGION}
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
force-path-style: true # Required for S3-compatible storage
sync-interval: 5s # How often to sync WAL
snapshot-interval: 1h # Full snapshot frequency
retention: 168h # 7 days
retention-check-interval: 1h
validation-interval: 12h
データベースの種類別の保持戦略
プライマリデータベース(production.sqlite3):
sync-interval: 5s- データの耐久性を確保するため、頻繁に同期しますsnapshot-interval: 1h- 1 時間ごとにスナップショットを作成しますretention: 720h- 復旧用に 30 日間保持します
キャッシュデータベース(production_cache.sqlite3):
sync-interval: 10s- 重要度が低いため、負荷を軽減しますsnapshot-interval: 6h- スナップショットの頻度を下げますretention: 24h- 1 日間の保持で十分です
キューデータベース(production_queue.sqlite3):
sync-interval: 5s- ジョブの耐久性を確保するため、重要ですsnapshot-interval: 1h- 1 時間ごとに作成しますretention: 72h- デバッグ用に 3 日間保持します
ケーブルデータベース(production_cable.sqlite3):
sync-interval: 10s- 一時的なデータですsnapshot-interval: 6h- 頻度を低くしますretention: 24h- 1 日間保持します
完全な設定例
dbs:
- path: /rails/storage/production.sqlite3
replicas:
- type: s3
bucket: myapp-backups
path: sqlite/production
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
force-path-style: true
sync-interval: 5s
snapshot-interval: 1h
retention: 720h
retention-check-interval: 1h
validation-interval: 12h
- path: /rails/storage/production_cache.sqlite3
replicas:
- type: s3
bucket: myapp-backups
path: sqlite/cache
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
force-path-style: true
sync-interval: 10s
snapshot-interval: 6h
retention: 24h
- path: /rails/storage/production_queue.sqlite3
replicas:
- type: s3
bucket: myapp-backups
path: sqlite/queue
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
force-path-style: true
sync-interval: 5s
snapshot-interval: 1h
retention: 72h
- path: /rails/storage/production_cable.sqlite3
replicas:
- type: s3
bucket: myapp-backups
path: sqlite/cable
endpoint: https://fsn1.your-objectstorage.com
region: fsn1
access-key-id: ${LITESTREAM_ACCESS_KEY_ID}
secret-access-key: ${LITESTREAM_SECRET_ACCESS_KEY}
force-path-style: true
sync-interval: 10s
snapshot-interval: 6h
retention: 24h
Kamal 2 のデプロイ
config/deploy.yml で Litestream をアクセサリーとして追加します。
accessories:
litestream:
image: litestream/litestream:0.3
host: <SERVER_IP>
cmd: replicate
volumes:
- "myapp_storage:/rails/storage:ro" # Read-only access
files:
- config/litestream.yml:/etc/litestream.yml
env:
secret:
- LITESTREAM_ACCESS_KEY_ID
- LITESTREAM_SECRET_ACCESS_KEY
options:
health-cmd: "litestream databases || exit 1"
health-interval: 30s
health-timeout: 5s
health-retries: 3
重要なポイント:
- ストレージを読み取り専用(
:ro)でマウントします。Litestream は WAL ファイルの読み取りのみを行います - メインアプリと同じボリューム名を使用します
- ヘルスチェックにより、Litestream がデータベースを認識できることを確認します
シークレットの設定
.kamal/secrets で設定します。
LITESTREAM_ACCESS_KEY_ID=$(op read "op://myproject/production-s3/access_key_id")
LITESTREAM_SECRET_ACCESS_KEY=$(op read "op://myproject/production-s3/secret_access_key")
災害復旧
データベースの復元
# Stop application first
kamal app stop
# Restore from latest backup
docker run --rm \
-v myapp_storage:/rails/storage \
-e LITESTREAM_ACCESS_KEY_ID="$(op read 'op://myproject/production-s3/access_key_id')" \
-e LITESTREAM_SECRET_ACCESS_KEY="$(op read 'op://myproject/production-s3/secret_access_key')" \
litestream/litestream:0.3 restore \
-config /etc/litestream.yml \
/rails/storage/production.sqlite3
# Restart application
kamal app start
特定時点への復旧
docker run --rm \
-v myapp_storage:/rails/storage \
-e LITESTREAM_ACCESS_KEY_ID="..." \
-e LITESTREAM_SECRET_ACCESS_KEY="..." \
litestream/litestream:0.3 restore \
-config /etc/litestream.yml \
-timestamp "2025-01-15T10:30:00Z" \
/rails/storage/production.sqlite3
監視
バックアップの状態を確認します。
# Via Kamal
kamal accessory exec litestream -- litestream databases
# Direct on server
docker exec myapp-litestream litestream databases
S3 互換ストレージ
Litestream はあらゆる S3 互換ストレージで動作します。
| プロバイダー | エンドポイントの例 |
|---|---|
| Hetzner Object Storage | https://fsn1.your-objectstorage.com |
| Backblaze B2 | https://s3.us-west-002.backblazeb2.com |
| DigitalOcean Spaces | https://nyc3.digitaloceanspaces.com |
| AWS S3 | (エンドポイントは省略し、リージョンを使用) |
重要: AWS 以外の S3 互換ストレージでは、必ず force-path-style: true を設定してください。
VACUUM が Litestream に与える影響
完全な VACUUM はデータベースファイル全体を書き換えます。Litestream はこれを完全な変更として検出し、(増分 WAL 同期ではなく)完全なスナップショットのアップロードを開始します。
運用上の考慮事項:
- VACUUM によりバックアップストレージの使用量が一時的に増加します(保持期間中は古いスナップショットと新しいスナップショットの両方が保持されます)
- 帯域幅の急増を避けるため、データベースごとに VACUUM の実施時間をずらします。プライマリは 3:00、キャッシュは 3:15、キューは 3:30 に実行します
- これは想定された安全な動作です。スナップショットを避けるために VACUUM を無効にしないでください
- VACUUM 後に
litestream databasesで監視し、スナップショットが完了したことを確認します
VACUUM のスケジュール戦略については、resources/database-admin/sqlite.md を参照してください。
ベストプラクティス
- 保持期間の要件に応じてデータベースを分ける - メインの DB はキャッシュよりも長い保持期間が必要です
- バックアップの遅延を監視する -
litestream databasesでレプリケーションの状態を確認できます - 定期的に復元をテストする - バックアップが機能することを確認するために、災害が起きるまで待たないでください
- 読み取り専用でマウントする - Litestream は WAL ファイルの読み取りのみを行います。
:roにより事故を防げます - VACUUM の実行時間をずらす - 複数のデータベースで完全なスナップショットが同時に作成されるのを防ぎます