当前位置:首页 > 技术分享 > 正文内容

centos 宝塔服务器上如何将网站文件定时自动备份到gitee.com

admin3周前 (08-08)技术分享89

核心逻辑

  1. 为每个网站创建独立的Gitee仓库

  2. 使用Git实现增量备份(只提交新增/修改文件)

  3. 通过宝塔定时任务每天自动执行

  4. 遇到冲突时强制以本地文件覆盖远程(git push -f

步骤1:前期准备

1.1 在Gitee创建仓库

  • 登录Gitee

  • 每个网站创建独立私有仓库(如:site1-backupsite2-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
fi

2.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 通过宝塔面板设置(推荐)

  1. 登录宝塔面板 → 计划任务

  2. 添加任务:

    • 任务类型:Shell脚本

    • 任务名称:备份网站A到Gitee

    • 执行周期:每天 3:00 AM

    • 脚本内容/www/backup_scripts/backup_site1.sh

  3. 重复添加其他网站的备份任务

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仓库
# 应看到初始提交,包含网站所有文件

关键功能说明

  1. 增量备份

    • git add -u + git reset -- <deleted_files> 组合实现只提交新增/修改

    • rsync 同步时保留文件属性

  2. 冲突处理git push -f 强制覆盖远程

  3. 安全措施

    • 使用临时目录隔离操作

    • 每次清理临时文件

    • SSH密钥加密通信

  4. 资源优化

    • 无额外存储占用(临时目录用完即删)

    • 避免完整压缩包传输

常见问题排查

# 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

实际部署时需替换:

  1. 网站路径(/www/wwwroot/your_website

  2. Gitee仓库地址(git@gitee.com:yourname/repo.git

  3. 备份执行时间(根据服务器负载调整)


扫描二维码推送至手机访问。

版权声明:本文由小刚刚技术博客发布,如需转载请注明出处。

本文链接:https://blog.bitefu.net/post/682.html

标签: git
分享给朋友:

相关文章

apicloud开发调试方法 nodejs [超低,超省内存占用] 兼容最新用友 you-cli

apicloud 开发 + 模拟器 +浏览器 +其它这些一开相当占用内存,让电脑不堪重负.于是我想到用命令行来实现调试这样可以不开启apicloud软件进行调试了 命令行+ 模拟器 就可以调试了准备1.检出项目.可以用svn检出,也可以直接...

节假日api 负载均衡升级 增加阿里云服务器

2024-8-19 vip服务器遭受攻击 现已经临时更换服务器以下是服务器的情况可根据自己的需求进行选择1.tool.bitefu.net 整合服务器到 新的阿里云服务器(配置更高),旧服务器已不再续费2.vip.bitefu.n...

360浏览器如何禁止切换到兼容模式[本地终极办法]

360浏览器如何禁止切换到兼容模式[本地终极办法]

浏览器内核控制标签meta说明背景介绍由于众所周知的原因,国内的主流浏览器都是双核浏览器:基于Webkit的内核用于常用网站的高速浏览,基于IE的内核主要用于部分网银、政府、办公系统等网站的正常使用。以360浏览器为例,我们优先通过Webk...

centos 配置Let's Encrypt 泛域名https证书

centos 配置Let's Encrypt 泛域名https证书

前言2018年1月份Letsencrypt可以申请泛域名证书,这让我们部署多域名、多站点https省了很多功夫,终于可以不用维护多个域名的https证书。笔者以acme.sh为例,手把手教你配置https证书~本教程适用于centos 6....

系统小技巧:微软版“Ghost” Windows FFU 系统安装还原

系统小技巧:微软版“Ghost” Windows FFU 系统安装还原

在日常的维护中,系统的备份和还原是大家经常需要操作的事情。虽然Windows 10已经提供很多的工具,如系统还原、WIM备份/还原,VHD备份等。不过这些工具大多是基于文件的备份/还原。我们以前经常的使用的Ghost则是基于扇区的备份/还原...

VirtualXposed 不支持32位应用 32位无法安装问题解决办法

VirtualXposed 不支持32位应用 32位无法安装问题解决办法

VirtualXposed 是基于VirtualApp 和 epic 在非ROOT环境下运行Xposed模块的实现(支持5.0~10.0)。与 Xposed 相比,目前 VirtualXposed 有...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。