wiki / scripts /backup.sh
gaojintao01
yh
420c7cb
#!/bin/bash
set -e
echo "--- [$(date)] Background Backup Service Initializing ---"
# --- 初始启动延迟 ---
echo "--- [$(date)] Initial startup delay. Waiting 90 seconds before starting backup cycles... ---"
sleep 90
# --- 主循环 ---
while true; do
# 将环境变量传递给flock内部
flock -n /tmp/backup.lock bash -c '
set -e
echo "--- [$(date)] Starting Scheduled Backup ---"
# --- 变量与暂存区定义 ---
LIVE_DATA_DIR="/app/server/storage"
LIVE_DB_FILE="/app/server/anythingllm.db"
STAGE_DIR="/tmp/backup_stage"
# --- 步骤 1: 清理并创建干净的暂存区 ---
echo "[Backup] Preparing a clean staging area at ${STAGE_DIR}..."
rm -rf "${STAGE_DIR}"
mkdir -p "${STAGE_DIR}/storage"
# --- 步骤 2: 安全地创建数据库快照并复制到暂存区 ---
echo "[Backup] Creating a safe snapshot of the SQLite database..."
if [ ! -f "${LIVE_DB_FILE}" ]; then
echo "[Error] Database file not found: ${LIVE_DB_FILE}"
exit 1
fi
sqlite3 "${LIVE_DB_FILE}" ".backup '${STAGE_DIR}/anythingllm.db'"
if [ $? -ne 0 ]; then
echo "[Error] Failed to create database backup"
exit 1
fi
# --- 步骤 3: 将线上数据目录同步到暂存区 ---
echo "[Backup] Syncing live data to the staging area..."
rsync -a --delete "${LIVE_DATA_DIR}/" "${STAGE_DIR}/storage/"
# --- 步骤 4: 从隔离的暂存区执行备份 ---
# --- 4a. WebDAV 备份 ---
if [ -n "${WEBDAV_URL}" ]; then
echo "[Backup] Syncing from staging area to WebDAV..."
rclone sync "${STAGE_DIR}/" "webdav:anythingllm_backup/" --create-empty-src-dirs
echo "[Backup] WebDAV sync completed."
fi
# --- 4b. GitHub 备份 ---
if [ -n "${GITHUB_REPO}" ]; then
echo "[Backup] Pushing from staging area to GitHub..."
cd "${STAGE_DIR}"
if [ ! -d ".git" ]; then
git init -b main
git config --global user.email "backup-bot@example.com"
git config --global user.name "Backup Bot"
git remote add origin https://${GITHUB_TOKEN}@github.com/${GITHUB_REPO}
fi
git add .
if ! git diff-index --quiet HEAD --; then
git commit -m "Automated backup: $(date -u)"
git push -u origin main -f
echo "[Backup] Pushed changes to GitHub."
else
echo "[Backup] No changes to commit to GitHub."
fi
fi
# --- 步骤 5: 清理暂存区 ---
echo "[Backup] Cleaning up staging area..."
rm -rf "${STAGE_DIR}"
# --- 步骤 6: 发送成功心跳 ---
if [ -n "${HEALTHCHECK_URL}" ]; then
echo "[Backup] Sending success ping..."
curl -fsS -m 10 --retry 3 ${HEALTHCHECK_URL} > /dev/null || echo "[Warning] Health check ping failed."
fi
echo "--- [$(date)] Backup Finished ---"
' "${BACKUP_INTERVAL:-3600}"
sleep ${BACKUP_INTERVAL:-3600}
done