centos 宝塔服务器上如何将网站文件定时自动备份到gitee.com
核心逻辑
为每个网站创建独立的Gitee仓库
使用Git实现增量备份(只提交新增/修改文件)
通过宝塔定时任务每天自动执行
遇到冲突时强制以本地文件覆盖远程(
git push -f)
步骤1:前期准备
1.1 在Gitee创建仓库
登录Gitee
为每个网站创建独立私有仓库(如:
site1-backup、site2-backup)记录仓库SSH地址(格式:
git@gitee.com:yourname/site1-backup.git)
1.2 服务器环境配置
# 安装Git yum install -y git # 配置全局用户信息(用于提交记录) git config --global user.name "ServerBackup" git config --global user.email "backup@yourserver.com"
1.3 生成SSH密钥并添加到Gitee
#生成密钥(一路回车默认) ssh-keygen -t rsa -b 4096 -C "server_backup_key" # 查看公钥 cat ~/.ssh/id_rsa.pub # 将公钥添加到 Gitee: # 个人设置 -> SSH公钥 -> 粘贴内容
1.4 测试SSH连接
ssh -T git@gitee.com # 看到 "Welcome to Gitee.com" 表示成功
步骤2:为每个网站创建备份脚本
2.1 脚本存放目录
mkdir -p /www/backup_scripts cd /www/backup_scripts
2.2 创建备份脚本模板
vim /www/backup_scripts/backup_template.sh
#!/bin/bash
# ----- 配置区 -----
WEBSITE_PATH="/www/wwwroot/your_website" # 网站目录
GITEE_REPO="git@gitee.com:yourname/repo.git" # Gitee仓库地址
TEMP_DIR="/tmp/git_temp_backup" # 临时工作目录
# ------------------
# 确保rsync可用
if ! command -v rsync &> /dev/null; then
echo "安装rsync..."
yum install rsync -y
fi
# 设置Git默认分支为main(消除警告)
git config --global init.defaultBranch main
# 创建临时目录
rm -rf $TEMP_DIR > /dev/null 2>&1
mkdir -p $TEMP_DIR
# 复制网站文件到临时目录(保留权限和时间戳)
cp -Rp $WEBSITE_PATH/* $TEMP_DIR/ > /dev/null 2>&1
# 初始化Git仓库
cd $TEMP_DIR
git init --initial-branch=main > /dev/null 2>&1
git remote add origin $GITEE_REPO > /dev/null 2>&1
# 尝试拉取现存备份(忽略错误)
git pull origin main 2>/dev/null || true
# 添加所有文件(但不提交删除操作)
for file in $(git status --porcelain | grep -v '^ D' | awk '{print $2}'); do
git add "$file"
done
# 提交变更
if [ -n "$(git status --porcelain)" ]; then
git commit -m "自动备份 $(date '+%Y-%m-%d %H:%M:%S')" > /dev/null
git push -f origin main > /dev/null 2>&1
echo "[成功] 网站已备份:${WEBSITE_PATH##*/} ($(du -sh $TEMP_DIR | awk '{print $1}'))"
else
echo "[跳过] 无文件变更:${WEBSITE_PATH##*/}"
fi
# 清理临时文件
rm -rf $TEMP_DIR > /dev/null 2>&1进阶脚本(针对大文件进行优化并排除特定文件)
#!/bin/bash
# ----- 配置区 -----
WEBSITE_PATH="/www/wwwroot/your_website"
GITEE_REPO="git@gitee.com:yourname/repo.git"
LOCAL_GIT_DIR="/www/git_backups/your_website"
SNAPSHOT_DIR="/www/snapshots/your_website"
MAX_FILE_SIZE="50M"
LOG_FILE="/var/log/website_backup_$(date +\%Y\%m\%d).log" # 每日日志文件
# 排除规则
EXCLUDE_DIRS=(".git" ".svn" ".idea" "__pycache__" "node_modules" "cache" "tmp" "logs")
EXCLUDE_FILES=("*.zip" "*.rar" "*.7z" "*.tar.*" "*.log" "*.tmp" "*.sql" "*.bak")
# ------------------
# 初始化日志
exec > >(tee -a "${LOG_FILE}") 2>&1
echo "===== 备份开始 [$(date '+%Y-%m-%d %H:%M:%S')] ====="
# 测试Gitee连接
test_gitee_connection() {
echo "测试Gitee SSH连接..."
ssh -T git@gitee.com
if [ $? -ne 0 ]; then
echo "错误:无法连接到Gitee!请检查SSH密钥配置。"
return 1
fi
return 0
}
# 确保必要工具安装
install_if_needed() {
for cmd in "$@"; do
if ! command -v $cmd &> /dev/null; then
echo "安装 $cmd..."
yum install -y $cmd
fi
done
}
# 安全推送函数(带重试)
git_push_with_retry() {
local retry_count=0
local max_retries=3
while [ $retry_count -lt $max_retries ]; do
echo "尝试推送 (尝试 #$((retry_count+1)))..."
git push -f origin main
if [ $? -eq 0 ]; then
echo "推送成功!"
return 0
fi
retry_count=$((retry_count+1))
echo "推送失败,10秒后重试..."
sleep 10
done
echo "错误:推送失败,已达最大重试次数!"
return 1
}
# 主函数
main() {
# 前置检查
test_gitee_connection || return 1
install_if_needed git rsync
# 设置Git默认分支
git config --global init.defaultBranch main > /dev/null 2>&1
#git config --global user.name "Server Backup"
#git config --global user.email "backup@yourserver.com"
# 1. 确保本地Git仓库正确初始化
echo "[阶段0] 初始化Git仓库..."
mkdir -p "$LOCAL_GIT_DIR"
cd "$LOCAL_GIT_DIR"
# 初始化Git仓库
if [ ! -d ".git" ]; then
echo "创建新的Git仓库..."
git init --initial-branch=main || { echo "错误:Git仓库初始化失败"; return 1; }
git remote add origin "$GITEE_REPO" || { echo "错误:添加远程仓库失败"; return 1; }
# 创建.gitignore
cat > .gitignore <<EOF
# 自动生成排除规则
*.[zZ][iI][pP]
*.[rR][aA][rR]
*.[7][zZ]
*.tar.*
*.log
*.tmp
*.sql
*.bak
*.cache
EOF
for dir in "${EXCLUDE_DIRS[@]}"; do
echo "$dir/" >> .gitignore
done
# 初始提交
git add .gitignore
git commit -m "初始化备份仓库" || { echo "错误:初始提交失败"; return 1; }
fi
# 2. 创建硬链接快照
echo "[阶段1] 创建文件系统快照..."
mkdir -p "$SNAPSHOT_DIR"
find "$SNAPSHOT_DIR" -mindepth 1 -delete 2>/dev/null
# 构建find排除参数
FIND_EXCLUDE=()
for pattern in "${EXCLUDE_DIRS[@]}" "${EXCLUDE_FILES[@]}"; do
FIND_EXCLUDE+=(-not -path "*/$pattern/*" -not -name "$pattern")
done
# 使用硬链接复制文件
echo "创建硬链接..."
find "$WEBSITE_PATH" -type f "${FIND_EXCLUDE[@]}" -size -$MAX_FILE_SIZE -print0 | \
while IFS= read -r -d $'\0' file; do
rel_path="${file#$WEBSITE_PATH/}"
target_dir="$SNAPSHOT_DIR/$(dirname "$rel_path")"
mkdir -p "$target_dir"
ln "$file" "$SNAPSHOT_DIR/$rel_path" 2>/dev/null
done
# 3. 增量同步到Git仓库
echo "[阶段2] 增量同步到Git仓库..."
rsync -a --delete \
--exclude='.git' \
"$SNAPSHOT_DIR/" "$LOCAL_GIT_DIR/"
# 4. 高效提交变更
echo "[阶段3] 检测并提交变更..."
cd "$LOCAL_GIT_DIR"
# 添加所有变更文件
git add -A .
# 检查并提交变更
if [ -n "$(git status --porcelain)" ]; then
git commit -m "增量备份 $(date '+%Y-%m-%d %H:%M')" || { echo "错误:提交失败"; return 1; }
# 获取远程状态
git fetch origin main
# 尝试合并或重置
git merge -X ours origin/main || git reset --hard origin/main
# 推送到远程
echo "[阶段4] 推送到Gitee..."
git_push_with_retry || return 1
# 仓库维护
git reflog expire --expire=now --all
git gc --prune=now --aggressive
echo "[成功] 备份完成"
echo "变更文件: $(git diff --shortstat HEAD~1)"
else
echo "[跳过] 无文件变更"
fi
# 清理快照目录
echo "清理快照目录..."
rm -rf "$SNAPSHOT_DIR"/*
echo "===== 备份结束 [$(date '+%Y-%m-%d %H:%M:%S')] ====="
return 0
}
# 执行主函数
if main; then
echo "备份成功完成!"
else
echo "备份过程中出现错误!请检查日志:$LOG_FILE"
exit 1
fi2.3 为每个网站创建专属脚本
# 示例:网站1 cp backup_template.sh backup_site1.sh sed -i 's|/www/wwwroot/your_website|/www/wwwroot/site1|g' backup_site1.sh sed -i 's|git@gitee.com:yourname/repo.git|git@gitee.com:yourname/site1-backup.git|g' backup_site1.sh # 同理为其他网站创建:# cp backup_template.sh backup_site2.sh # 修改对应路径和仓库地址
2.4 赋予执行权限
chmod +x /www/backup_scripts/*.sh
步骤3:设置定时任务
3.1 通过宝塔面板设置(推荐)
登录宝塔面板 → 计划任务
添加任务:
任务类型:Shell脚本
任务名称:备份网站A到Gitee
执行周期:每天 3:00 AM
脚本内容:
/www/backup_scripts/backup_site1.sh重复添加其他网站的备份任务
3.2 手动配置Crontab(备用)
# 编辑crontab crontab -e # 添加以下内容(每天凌晨3点执行) 0 3 * * * /www/backup_scripts/backup_site1.sh >> /var/log/backup_site1.log 2>&1 0 4 * * * /www/backup_scripts/backup_site2.sh >> /var/log/backup_site2.log 2>&1 # 重启cron服务systemctl restart crond
步骤4:首次手动执行测试
# 测试脚本 cd /www/backup_scripts ./backup_site1.sh # 查看日志cat /var/log/backup_site1.log # 检查Gitee仓库 # 应看到初始提交,包含网站所有文件
关键功能说明
增量备份
git add -u+git reset -- <deleted_files>组合实现只提交新增/修改rsync同步时保留文件属性冲突处理
git push -f强制覆盖远程安全措施
使用临时目录隔离操作
每次清理临时文件
SSH密钥加密通信
资源优化
无额外存储占用(临时目录用完即删)
避免完整压缩包传输
常见问题排查
# 1. 权限问题 chown -R www:www /www/backup_scripts/*.sh # 2. Git推送失败 ssh -T git@gitee.com # 验证密钥 git config --global --add safe.directory '*' # 解决CVE-2022-24765 # 3. 查看详细日志 tail -f /var/log/backup_site1.log # 4. 手动运行调试 cd /www/backup_scriptsbash -x backup_site1.sh
实际部署时需替换:
网站路径(
/www/wwwroot/your_website)Gitee仓库地址(
git@gitee.com:yourname/repo.git)备份执行时间(根据服务器负载调整)


