43 lines
2.0 KiB
Bash
Executable File
43 lines
2.0 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
archive="${1:-}"
|
|
if [ -z "$archive" ] || [ ! -f "$archive" ]; then echo "用法: CONFIRM_RESTORE=yes BACKUP_ENCRYPTION_PASSWORD=... sh scripts/restore.sh /绝对路径/备份.enc" >&2; exit 2; fi
|
|
if [ "${CONFIRM_RESTORE:-}" != "yes" ]; then echo "恢复会覆盖当前数据库和上传素材,请设置 CONFIRM_RESTORE=yes" >&2; exit 2; fi
|
|
backup_password="${BACKUP_ENCRYPTION_PASSWORD:-}"
|
|
if [ "${#backup_password}" -lt 20 ]; then echo "BACKUP_ENCRYPTION_PASSWORD 至少需要 20 个字符" >&2; exit 2; fi
|
|
|
|
archive_dir="$(cd "$(dirname "$archive")" && pwd)"
|
|
archive_name="$(basename "$archive")"
|
|
restore_id="$(date +%Y%m%d-%H%M%S)"
|
|
|
|
echo "停止应用并保留恢复前备份…"
|
|
BACKUP_ENCRYPTION_PASSWORD="$BACKUP_ENCRYPTION_PASSWORD" sh scripts/backup.sh daily
|
|
docker compose stop web
|
|
|
|
cleanup() { docker compose start web >/dev/null 2>&1 || true; }
|
|
trap cleanup EXIT INT TERM
|
|
|
|
docker compose run --rm --no-deps \
|
|
-v "$archive_dir:/restore-source:ro" \
|
|
-e RESTORE_ARCHIVE="/restore-source/$archive_name" \
|
|
-e RESTORE_ID="$restore_id" \
|
|
-e BACKUP_ENCRYPTION_PASSWORD="$BACKUP_ENCRYPTION_PASSWORD" \
|
|
web sh -eu -c '
|
|
restore_dir="/app/data/restore-$RESTORE_ID"
|
|
mkdir -p "$restore_dir"
|
|
openssl enc -d -aes-256-cbc -pbkdf2 -iter 200000 \
|
|
-pass env:BACKUP_ENCRYPTION_PASSWORD -in "$RESTORE_ARCHIVE" | tar -xzf - -C "$restore_dir"
|
|
test -f "$restore_dir/huiyu.sqlite"
|
|
node -e "const Database=require(\"better-sqlite3\"); const db=new Database(process.argv[1],{readonly:true}); const result=db.pragma(\"integrity_check\",{simple:true}); db.close(); if(result!==\"ok\") process.exit(1)" "$restore_dir/huiyu.sqlite"
|
|
rm -f /app/data/db/huiyu.sqlite /app/data/db/huiyu.sqlite-wal /app/data/db/huiyu.sqlite-shm
|
|
cp "$restore_dir/huiyu.sqlite" /app/data/db/huiyu.sqlite
|
|
rm -rf /app/data/uploads
|
|
cp -R "$restore_dir/uploads" /app/data/uploads
|
|
rm -rf "$restore_dir"
|
|
'
|
|
|
|
docker compose start web
|
|
trap - EXIT INT TERM
|
|
echo "恢复完成。请执行: docker compose ps && curl -fsS http://localhost:3000/api/health"
|