PrismaのSQLiteをcronで自動バックアップする手順

※本記事にはプロモーション(広告・アフィリエイトリンク)を含みます。
自作のECサイトで Prisma + SQLite を運用していて、「データが飛んだらどうするか」を真剣に考えたのは systemd で常駐化してからです。cron で定期バックアップを仕込む手順を、実際の構成をもとに整理します。
SQLiteバックアップの3つの方法と選択基準
SQLiteのバックアップには主に3つの方法があります。
| 方法 | 特徴 | WAL使用時の安全性 |
|---|---|---|
sqlite3 db.db ".backup 'backup.db'" |
オンラインバックアップAPI | ✅ 安全 |
VACUUM INTO 'backup.db' |
デフラグしながらコピー | ✅ 安全 |
cp dev.db backup.db |
単純コピー | ⚠️ 不整合の可能性あり |
単純な cp は避けたほうが安全です。 WAL(Write-Ahead Logging)モードを使っている場合、-wal ファイルに書き込みが残っているタイミングでコピーすると、バックアップが不整合になる可能性があります。sqlite3 .backup コマンドはSQLite組み込みのオンラインバックアップAPIを使うため、サービスが稼働中でも整合性が保たれます。
WALモードの仕組みについてはSQLite WALモード設定ガイド:仕組みからPrismaでの実装までで解説しています。
sqlite3 CLIの確認
sqlite3 --version
入っていなければインストールします。
# Ubuntu/Debian系
sudo apt install sqlite3
PrismaはSQLiteバインディングを内蔵していますが、.backup コマンドには別途 sqlite3 CLIが必要です。
バックアップスクリプトを書く
私の構成では ~/ec-site/prisma/dev.db が本番DBです。これを /mnt/data/backups/ec-site/ に日付付きで保存するスクリプトを作ります。
#!/bin/bash
# ~/scripts/backup-ecsite-db.sh
set -euo pipefail
DB_PATH="$HOME/ec-site/prisma/dev.db"
BACKUP_DIR="/mnt/data/backups/ec-site"
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/dev_${DATE}.db"
LOG_FILE="$HOME/logs/ec-backup.log"
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
# SQLiteオンラインバックアップAPIでコピー
sqlite3 "$DB_PATH" ".backup '${BACKUP_FILE}'"
# 整合性チェック
INTEGRITY=$(sqlite3 "$BACKUP_FILE" "PRAGMA integrity_check;")
if [ "$INTEGRITY" != "ok" ]; then
echo "[$(date)] ERROR: integrity_check failed: $INTEGRITY" | tee -a "$LOG_FILE" >&2
rm -f "$BACKUP_FILE"
exit 1
fi
echo "[$(date)] OK: $BACKUP_FILE" | tee -a "$LOG_FILE"
# 7日より古いファイルを削除(世代管理)
find "$BACKUP_DIR" -name "dev_*.db" -mtime +7 -delete
実行権限を付与します。
chmod +x ~/scripts/backup-ecsite-db.sh
スクリプトのポイント解説
set -euo pipefail
エラー発生時に即座に終了します。u は未定義変数の参照を禁止、pipefail はパイプ中のエラーも拾います。バックアップスクリプトで「コケても気づかない」状態を防ぐための基本設定です。
.backup のクォートに注意
.backup はSQLのコマンドではなくsqlite3のメタコマンドです。ファイルパスにスペースが含まれる場合はシングルクォートで囲む必要があります(上記スクリプトでは対応済み)。
PRAGMA integrity_check を必ず入れる
バックアップ直後に検証します。ok 以外が返ってきたらバックアップを削除してエラー終了します。これを省くと壊れたバックアップを何日も蓄積してしまいます。
-mtime +7 の意味
find の -mtime +7 は「変更から168時間以上経過したファイル」です。直感では「7日前以前」ですが、実際には「8日前以降に作ったファイル」が対象になります。初回は -delete を外して対象ファイルを確認してから本番に入れることをすすめます。
cronで自動実行する
crontab -e
毎日午前3時に実行する例です。私の環境ではClamAVのスキャンが4時30分に走るため、それより前に設定しています。
MAILTO=""
0 3 * * * /home/kxkxk/scripts/backup-ecsite-db.sh 2>> /home/kxkxk/logs/ec-backup-err.log
MAILTO="" はcronのエラーメールを止めるための設定です。その場合、スクリプトが見つからない等のcronレベルのエラーが消えてしまうため、2>> でエラーログを別ファイルに残しています。
動作確認
設定後は必ず手動実行して確認します。
~/scripts/backup-ecsite-db.sh
[2026-08-22 03:00:01] OK: /mnt/data/backups/ec-site/dev_20260822_030001.db
このようなログが出ればOKです。バックアップファイルを直接確認することもできます。
sqlite3 /mnt/data/backups/ec-site/dev_20260822_030001.db "PRAGMA integrity_check;"
# ok と出れば正常
保存先の設計:NVMeとHDDの使い分け
私の構成では、NVMe(~/)はディスクが逼迫しやすいためバックアップはHDD(/mnt/data/)に置いています。
| 保存先 | 用途 |
|---|---|
~/ec-site/prisma/dev.db |
本番DB(NVMe) |
/mnt/data/backups/ec-site/ |
バックアップ保存先(HDD) |
同一マシン内だけでは物理障害に対応できません。 余裕があればrsyncで別マシンにも転送することを検討してください。
# リモートマシン側から実行
rsync -avz --checksum \
user@your-server:/mnt/data/backups/ec-site/ \
~/Backups/ec-site/
ディスク管理の全体についてはLinuxディスク使用量の確認と整理|df・du・ログ削除の手順も参考になります。
復元手順を事前に確認する
バックアップは復元できて初めて意味を持ちます。手順を事前に確認しておきましょう。
1. サービスを停止する
sudo systemctl stop ec-site.service
2. 現在のDBを念のため退避する
cp ~/ec-site/prisma/dev.db ~/ec-site/prisma/dev.db.before-restore
3. バックアップから復元する
# .restore コマンドを使う方法
sqlite3 ~/ec-site/prisma/dev.db \
".restore '/mnt/data/backups/ec-site/dev_20260820_030001.db'"
# またはサービス停止中なら cp でも可
cp /mnt/data/backups/ec-site/dev_20260820_030001.db \
~/ec-site/prisma/dev.db
4. 整合性確認
sqlite3 ~/ec-site/prisma/dev.db "PRAGMA integrity_check;"
# ok と出ることを確認
5. サービスを再起動する
sudo systemctl start ec-site.service
sudo systemctl status ec-site.service
古すぎるバックアップから復元すると、マイグレーション状態とDBスキーマがずれる場合があります。復元後は以下のコマンドも確認してください。
cd ~/ec-site && npx prisma migrate status
まとめ
Prisma + SQLite 環境のバックアップは、sqlite3 .backup + PRAGMA integrity_check + cronの組み合わせが確実です。cp より整合性が高く、systemdサービスが動いている最中でも安全に実行できます。
まず手動実行から始めてください。 スクリプトを作って chmod +x し、手動実行でバックアップファイルと integrity_check の結果を確認する。それができたら cron に1行追加するだけです。
よくある質問
PrismaのSQLiteをcpコマンドでバックアップしても問題ないですか?
WALモード有効時は `-wal` ファイルに書き込みが残っているタイミングでコピーすると不整合になる可能性があります。`sqlite3 .backup` コマンドはオンラインバックアップAPIを使うため、サービス稼働中でも安全です。
PrismaにはDBのバックアップコマンドが組み込まれていますか?
Prismaにはバックアップコマンドはありません。バックアップにはsqlite3 CLIの `.backup` コマンドか `VACUUM INTO` を使います。Prismaはスキーマ管理とクエリのためのツールであり、バックアップ機能は持っていません。
cronのバックアップが実行されたか確認するには?
スクリプト内でログファイル(`~/logs/ec-backup.log`)に書き込んでおくのが確実です。`cat ~/logs/ec-backup.log` で最新の実行結果を、`ls -lt /mnt/data/backups/ec-site/` でバックアップファイルの日時を確認できます。