website-scripts/backup/backup-full.sh

141 lines
5.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# 完整灾难恢复备份脚本
# 包含数据库、代码仓库、用户数据、配置文件、SSL证书
# 用法bash backup-full.sh
set -e
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOCAL_DIR="/Users/niuniu/programs/docker/db-backups"
BACKUP_NAME="full-backup-${TIMESTAMP}"
log() { echo "[$(date '+%H:%M:%S')] $1"; }
warn() { echo "[$(date '+%H:%M:%S')] [警告] $1"; }
log "开始完整灾难恢复备份..."
# ============================================================
# 1. 数据库备份WAL checkpoint + docker cp
# ============================================================
# 自动发现数据库站点
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
DB_SITES=""
for dir in "$PROJECT_ROOT"/*-ai/; do
s=$(basename "$dir"); [[ "$s" == "nginx-proxy-ai" ]] && continue
[ -f "$dir/docker-compose.yml" ] || continue
grep -qE "\.db|DATABASE_PATH|sqlite" "$dir/docker-compose.yml" 2>/dev/null || continue
[[ "$s" == "oa" ]] && continue; DB_SITES="$DB_SITES $s"
done
log "执行 WAL checkpoint..."
for s in $DB_SITES; do
case "$s" in
ldap) ssh txjp "docker exec lldap sqlite3 /data/users.db 'PRAGMA wal_checkpoint(TRUNCATE);'" 2>/dev/null || warn "ldap checkpoint 失败" ;;
*) ssh txjp "docker exec ${s} sqlite3 /app/data/*.db 'PRAGMA wal_checkpoint(TRUNCATE);' 2>/dev/null || true" & ;;
esac
done; wait
log "导出数据库..."
ssh txjp "mkdir -p /tmp/full-backup/databases"
for s in $DB_SITES; do
case "$s" in
ldap) ssh txjp "docker cp lldap:/data/users.db /tmp/full-backup/databases/ldap.db" ;;
gitea) ssh txjp "docker cp gitea-ai:/data/gitea.db /tmp/full-backup/databases/gitea.db" ;;
*) short="${s%-ai}"; ssh txjp "docker cp ${s}:/app/data/${short}.db /tmp/full-backup/databases/${short}.db" ;;
esac
done
# ============================================================
# 2. Gitea 代码仓库 + 配置
# ============================================================
log "备份 Gitea 代码仓库..."
ssh txjp "mkdir -p /tmp/full-backup/gitea && \
cp -a /root/docker/gitea-ai/data/git /tmp/full-backup/gitea/ && \
cp -a /root/docker/gitea-ai/data/gitea/conf /tmp/full-backup/gitea/ 2>/dev/null || true"
# ============================================================
# 3. 用户上传文件
# ============================================================
log "备份用户上传文件..."
ssh txjp "mkdir -p /tmp/full-backup/uploads && \
cp -a /root/docker/assets-ai/data/uploads /tmp/full-backup/uploads/assets-uploads 2>/dev/null || true && \
cp -a /root/docker/issue-ai/data/uploads /tmp/full-backup/uploads/issue-uploads 2>/dev/null || true && \
cp -a /root/docker/issue-ai/data/reports /tmp/full-backup/uploads/issue-reports 2>/dev/null || true"
# ============================================================
# 4. Nginx 配置
# ============================================================
log "备份 Nginx 配置..."
ssh txjp "mkdir -p /tmp/full-backup/nginx && \
cp -a /root/docker/nginx-proxy-ai/conf.d/* /tmp/full-backup/nginx/ 2>/dev/null || true"
# ============================================================
# 5. 各站点 docker-compose.yml + .env
# ============================================================
log "备份站点配置文件..."
ssh txjp "mkdir -p /tmp/full-backup/configs && \
for site in assets-ai issue-ai oa-ai ldap-ai gitea-ai; do \
mkdir -p /tmp/full-backup/configs/\$site && \
cp /root/docker/\$site/docker-compose.yml /tmp/full-backup/configs/\$site/ 2>/dev/null || true && \
cp /root/docker/\$site/.env /tmp/full-backup/configs/\$site/ 2>/dev/null || true && \
cp /root/docker/\$site/Dockerfile /tmp/full-backup/configs/\$site/ 2>/dev/null || true; \
done"
# ============================================================
# 6. SSL 证书
# ============================================================
log "备份 SSL 证书..."
ssh txjp "mkdir -p /tmp/full-backup/ssl && \
cp -a /etc/letsencrypt/live /tmp/full-backup/ssl/ 2>/dev/null || true && \
cp -a /etc/letsencrypt/archive /tmp/full-backup/ssl/ 2>/dev/null || true && \
cp -a /etc/letsencrypt/renewal /tmp/full-backup/ssl/ 2>/dev/null || true"
# ============================================================
# 7. 打包压缩
# ============================================================
log "打包压缩..."
ssh txjp "cd /tmp && tar czf ${BACKUP_NAME}.tar.gz full-backup/ && rm -rf /tmp/full-backup"
# ============================================================
# 8. 复制到本地
# ============================================================
log "复制到本地..."
mkdir -p "${LOCAL_DIR}"
scp "txjp:/tmp/${BACKUP_NAME}.tar.gz" "${LOCAL_DIR}/"
# ============================================================
# 9. 云端保留一份
# ============================================================
CLOUD_DIR="/root/docker/db-backups"
ssh txjp "mkdir -p ${CLOUD_DIR} && cp /tmp/${BACKUP_NAME}.tar.gz ${CLOUD_DIR}/"
log "云端备份已保存至: ${CLOUD_DIR}"
# ============================================================
# 10. 清理云端临时文件
# ============================================================
ssh txjp "rm -f /tmp/${BACKUP_NAME}.tar.gz"
# ============================================================
# 11. 验证备份
# ============================================================
log "验证备份完整性..."
cd "${LOCAL_DIR}"
if tar tzf "${BACKUP_NAME}.tar.gz" > /dev/null 2>&1; then
log "备份文件验证通过"
else
echo "[错误] 备份文件损坏"
exit 1
fi
# 显示备份内容
log "备份内容清单:"
tar tzf "${BACKUP_NAME}.tar.gz" | head -30
echo ""
log "备份完成:${TIMESTAMP}"
echo " 文件: ${LOCAL_DIR}/${BACKUP_NAME}.tar.gz"
echo " 大小: $(du -h ${LOCAL_DIR}/${BACKUP_NAME}.tar.gz | cut -f1)"
echo ""
echo " 云端: ${CLOUD_DIR}/${BACKUP_NAME}.tar.gz"
ssh txjp "ls -lh ${CLOUD_DIR}/${BACKUP_NAME}.tar.gz 2>/dev/null"