目标
本指南将引导您在 Debian 12 服务器上,配置一个自动化的脚本来完成以下任务:
- 每日自动备份 Typecho 博客的数据库和
usr目录。 - 将备份文件通过 Git 推送到一个私有的 GitHub 仓库。
- 自动清理超过30天的旧备份,节省空间。
- 在备份成功或失败时,通过 QQ 邮箱 和 Telegram Bot 发送即时通知。
1. 环境准备与配置
1.1 安装系统依赖
首先,更新系统软件包列表并安装 Python 3 的包管理器(pip)和虚拟环境工具(venv)。
sudo apt update
sudo apt install python3-pip python3-venv
1.2 创建项目目录结构
我们将创建两个目录来分别存放通知脚本和备份脚本,以保持整洁。
# 在您的主目录下创建项目文件夹
mkdir -p ~/backup_notifier
mkdir -p ~/backup_scripts
1.3 配置 Python 虚拟环境
为通知脚本创建一个独立的 Python 环境,以避免与系统库冲突。
# 进入通知脚本目录
cd ~/backup_notifier
# 创建一个名为 'venv' 的虚拟环境
python3 -m venv venv
# 激活虚拟环境
source venv/bin/activate
# 在激活的环境中,安装发送 Telegram 消息所需的库
pip install python-telegram-bot
# 完成后,可以暂时停用虚拟环境(后续脚本会自动调用)
# deactivate
2. 获取必要的凭证
在编写脚本之前,您需要从 QQ 邮箱和 Telegram 获取以下信息。
-
QQ 邮箱 SMTP 授权码
- 登录您的 QQ 邮箱网页版。
- 进入 设置 > 账户。
- 找到 “IMAP/SMTP服务” 并点击 开启。
- 根据提示完成安全验证,您将获得一个 16位的授权码。
-
Telegram Bot Token 和 Chat ID
- Bot Token:在 Telegram 中与
@BotFather对话,发送/newbot命令,按提示创建机器人后,您将获得一串 API Token。 - Chat ID:在 Telegram 中与
@userinfobot对话,发送/start命令,它会返回您的数字 Chat ID。
- Bot Token:在 Telegram 中与
3. 创建 Python 通知脚本
在 ~/backup_notifier 目录下创建一个名为 send_notification.py 的文件,并填入以下模板代码。
# 文件路径: ~/backup_notifier/send_notification.py
nano ~/backup_notifier/send_notification.py
将以下内容粘贴到文件中,并替换所有 "YOUR_..." 占位符。
import smtplib
import telegram
import asyncio
from email.mime.text import MIMEText
from email.utils import formataddr
from datetime import datetime
import sys
# --- ↓↓↓ 请在此处填入您的配置信息 ↓↓↓ ---
# QQ邮箱配置
SENDER_EMAIL = 'YOUR_QQ_EMAIL@qq.com'
AUTH_CODE = 'YOUR_16_DIGIT_AUTH_CODE'
RECEIVER_EMAIL = 'YOUR_RECEIVER_EMAIL@example.com'
# Telegram Bot配置
BOT_TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN'
CHAT_ID = 'YOUR_TELEGRAM_CHAT_ID'
# --- ↑↑↑ 配置结束 ↑↑↑ ---
def send_email_notification(subject, body):
try:
msg = MIMEText(body, 'plain', 'utf-8')
msg['From'] = formataddr(("博客备份系统", SENDER_EMAIL), 'utf-8')
msg['To'] = formataddr(("管理员", RECEIVER_EMAIL), 'utf-8')
msg['Subject'] = subject
server = smtplib.SMTP_SSL('smtp.qq.com', 465)
server.login(SENDER_EMAIL, AUTH_CODE)
server.sendmail(SENDER_EMAIL, [RECEIVER_EMAIL], msg.as_string())
server.quit()
print("邮件通知发送成功!")
return True
except Exception as e:
print(f"邮件发送失败: {e}", file=sys.stderr)
return False
async def send_telegram_notification(message):
try:
bot = telegram.Bot(token=BOT_TOKEN)
await bot.send_message(chat_id=CHAT_ID, text=message)
print("Telegram消息发送成功!")
return True
except Exception as e:
print(f"Telegram消息发送失败: {e}", file=sys.stderr)
return False
async def main():
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if len(sys.argv) > 1:
backup_status_message = " ".join(sys.argv[1:])
subject = f"博客备份结果通知 - {current_time}"
body = f"博客备份脚本执行完毕。\n时间: {current_time}\n结果: {backup_status_message}"
else:
subject = f"博客备份成功 - {current_time}"
body = f"您的博客已于 {current_time} 成功完成自动备份。"
print("开始发送通知...")
email_success = send_email_notification(subject, body)
telegram_success = await send_telegram_notification(body)
print("-" * 20)
if email_success and telegram_success:
print("所有通知均已成功发送。")
else:
print("部分或全部通知发送失败,请检查上方日志。")
if __name__ == '__main__':
asyncio.run(main())
4. 创建整合的 Shell 备份脚本
在 ~/backup_scripts 目录下创建一个名为 backup.sh 的文件。
# 文件路径: ~/backup_scripts/backup.sh
nano ~/backup_scripts/backup.sh
将以下内容粘贴进去,并替换所有 "YOUR_..." 占位符。
#!/bin/bash
# --- ↓↓↓ 请核对您的配置信息 ↓↓↓ ---
DB_USER="YOUR_DB_USER"
DB_PASS="YOUR_DB_PASSWORD"
DB_NAME="YOUR_DB_NAME"
TYPECHO_ROOT_DIR="/var/www/typecho" # Typecho网站根目录
BACKUP_REPO_DIR="/home/YOUR_USERNAME/typecho_backup_repo" # 本地备份仓库目录
GIT_REPO_URL="git@github.com:YOUR_GITHUB_USERNAME/YOUR_REPO_NAME.git" # 远程Git仓库地址
# 【重要】通知脚本的绝对路径配置
NOTIFIER_SCRIPT="/home/YOUR_USERNAME/backup_notifier/send_notification.py"
VENV_PYTHON="/home/YOUR_USERNAME/backup_notifier/venv/bin/python3"
# --- ↑↑↑ 配置结束 ↑↑↑ ---
send_notification() {
echo "正在发送通知: $1"
$VENV_PYTHON $NOTIFIER_SCRIPT "$1"
}
echo "--- [$(date '+%Y-%m-%d %H:%M:%S')] 开始备份 ---"
if [ ! -d "$BACKUP_REPO_DIR" ]; then
echo "本地仓库不存在,正在从GitHub克隆..."
git clone $GIT_REPO_URL $BACKUP_REPO_DIR
fi
cd $BACKUP_REPO_DIR || { send_notification "警报:无法进入备份目录 ${BACKUP_REPO_DIR}!"; exit 1; }
echo "正在清理30天前的旧备份..."
find . -type f -name 'db-backup-*.sql' -mtime +30 -delete
find . -type f -name 'usr-backup-*.tar.gz' -mtime +30 -delete
DATE_FORMAT=$(date "+%Y-%m-%d")
DB_BACKUP_FILE="db-backup-${DATE_FORMAT}.sql"
USR_BACKUP_FILE="usr-backup-${DATE_FORMAT}.tar.gz"
echo "正在备份数据库..."
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $DB_BACKUP_FILE
if [ $? -ne 0 ]; then
send_notification "警报:Typecho 数据库备份失败!请立即检查。"
exit 1
fi
echo "正在备份 usr 目录..."
tar -czf $USR_BACKUP_FILE -C $TYPECHO_ROOT_DIR usr
if [ $? -ne 0 ]; then
send_notification "警报:Typecho 'usr' 目录打包失败!请立即检查。"
exit 1
fi
echo "正在将备份推送到 GitHub..."
git pull origin main
git add .
git commit -m "自动备份于 ${DATE_FORMAT}"
git push origin main
if [ $? -ne 0 ]; then
send_notification "警告:备份文件已在本地生成,但推送到 GitHub 失败!"
exit 1
fi
SUCCESS_MESSAGE="Typecho 备份成功!文件 ${DB_BACKUP_FILE} 和 ${USR_BACKUP_FILE} 已生成并推送到 GitHub。"
send_notification "$SUCCESS_MESSAGE"
echo "--- [$(date '+%Y-%m-%d %H:%M:%S')] 备份和通知流程全部完成 ---"
保存后,为该脚本添加可执行权限:
chmod +x ~/backup_scripts/backup.sh
5. 设置 Cron 定时任务实现自动化
最后,我们使用 cron 来设置每日定时执行备份脚本。
-
打开
crontab编辑器:crontab -e -
在文件末尾添加以下一行,设置脚本在每天凌晨3点执行:
# 在每天的 03:00 执行Typecho备份脚本,并将日志输出到文件 0 3 * * * /bin/bash /home/YOUR_USERNAME/backup_scripts/backup.sh > /home/YOUR_USERNAME/backup_scripts/backup.log 2>&1请务必将
YOUR_USERNAME替换为您服务器的实际用户名。0 3 * * *:代表每天的 3 点 0 分。> .../backup.log 2>&1:将脚本的所有输出(包括错误信息)都重定向到backup.log文件中,方便日后排查问题。
6. 手动测试与验证
在等待定时任务自动执行前,强烈建议您手动运行一次脚本,以确保所有配置都正确无误。
bash ~/backup_scripts/backup.sh
观察终端输出,并检查您的邮箱和 Telegram 是否都收到了成功的通知。
至此,您的全自动博客备份与通知系统已部署完毕。