feat: 初始化慧遇书院官网一期

This commit is contained in:
2026-08-12 18:01:17 +08:00
commit 5d31ee5743
101 changed files with 17259 additions and 0 deletions

42
scripts/restore.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/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"