国庆节10月1日
--


介绍如何给 Waline 评论系统加一个自动备份到 GitHub 的脚本

数据库只有一个 SQLite 文件,丢了就真没了。写个脚本每天自动备份到 GitHub 私有仓库,安心。
Waline 默认使用 SQLite 存储数据,整个数据库就是一个 waline.sqlite 文件。好处是轻量、不需要额外装数据库;坏处是文件丢了就什么都没了。
虽然服务器有快照功能,但快照是整个系统的,恢复起来太重。不如写个脚本,每天把关键文件打包推到 GitHub,恢复的时候一条命令搞定。
data/ 目录(SQLite 数据库)和 docker-compose.yml 打包成 .tar.gz去 GitHub 新建一个仓库,一定要选 Private。名字随意,比如 waline-backup。
⚠️ Token 只会显示一次,务必保存好。如果泄露了,立刻去 GitHub 撤销。
1#!/bin/bash2WALINE_DIR="/opt/waline"3BACKUP_DIR="/opt/waline/backup"4GITHUB_USER="你的GitHub用户名"5GITHUB_REPO="waline-backup"6GITHUB_TOKEN="你的GitHub Token"7KEEP_DAYS=308
9log() {10 echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"11}12
13log "========== Waline 备份开始 =========="14mkdir -p "$BACKUP_DIR"15cd "$BACKUP_DIR"16
17# 首次运行:初始化 Git 仓库18if [ ! -d ".git" ]; then19 git init20 git remote add origin "https://${GITHUB_TOKEN}@github.com/${GITHUB_USER}/${GITHUB_REPO}.git"21 git config user.email "backup@waline.local"22 git config user.name "Waline Backup"23 git branch -m master main24fi25
26# 拉取远程最新27git fetch origin main 2>/dev/null28git reset --soft origin/main 2>/dev/null29
30# 打包31TIMESTAMP=$(date +%Y%m%d_%H%M%S)32BACKUP_FILE="waline-backup-${TIMESTAMP}.tar.gz"33
34log "正在打包..."35tar czf "$BACKUP_FILE" -C "$WALINE_DIR" data docker-compose.yml 2>/dev/null36
37if [ $? -ne 0 ]; then38 log "打包失败!"39 exit 140fi41
42FILE_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)43log "打包完成:${BACKUP_FILE} (${FILE_SIZE})"44
45# 清理旧备份46find "$BACKUP_DIR" -name "waline-backup-*.tar.gz" -mtime +${KEEP_DAYS} -delete47
48# 推送到 GitHub49git add -A50git commit -m "backup: ${TIMESTAMP}"51log "正在推送到 GitHub..."52git push origin main 2>&153
54if [ $? -eq 0 ]; then55 log "推送成功!"56else57 log "推送失败!"58 exit 159fi60
61# 本地只保留最近 7 个62ls -t waline-backup-*.tar.gz 2>/dev/null | tail -n +8 | xargs -r rm -f63
64log "========== Waline 备份完成 =========="把 GITHUB_USER 和 GITHUB_TOKEN 换成你自己的,保存为 /opt/waline/backup.sh。
1# 保存脚本2vi /opt/waline/backup.sh3# 粘贴上面的脚本内容,保存退出4
5# 设置执行权限6chmod +x /opt/waline/backup.sh7
8# 手动测试一次9/opt/waline/backup.sh看到 推送成功! 就说明没问题了。然后添加定时任务:
1# 添加到 crontab(每天凌晨 3 点执行)2(crontab -l 2>/dev/null; echo "0 3 * * * /opt/waline/backup.sh >> /opt/waline/backup/backup.log 2>&1") | crontab -3
4# 确认5crontab -l服务器到期、迁移、或者挂了,都需要在新机器上恢复。下面是完整的恢复流程。
1# Ubuntu / Debian2wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh3
4# CentOS5yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh登录宝塔面板,跳过 LNMP 套件安装。
宝塔面板 → 软件商店 → 搜索「Docker管理器」→ 安装。
或者手动安装:
1curl -fsSL https://get.docker.com | sh2systemctl start docker && systemctl enable docker1# 克隆备份仓库2mkdir -p /opt/waline3git clone https://你的Token@github.com/你的用户名/waline-backup.git /opt/waline/backup4
5# 找到最新的备份文件6ls -t /opt/waline/backup/waline-backup-*.tar.gz | head -17
8# 解压到 /opt/waline9cd /opt/waline10tar xzf backup/waline-backup-$(date +%Y%m%d)*.tar.gz11# 如果上面找不到文件,用这个(自动选最新的):12# tar xzf backup/$(ls -t backup/waline-backup-*.tar.gz | head -1)解压后目录结构应该是:
1/opt/waline/2├── data/3│ └── waline.sqlite # 数据库(所有评论、用户数据都在这里)4├── docker-compose.yml # 容器配置5└── backup/ # 备份目录1cd /opt/waline2docker compose up -d验证:
1docker ps # 容器应该在运行2curl http://127.0.0.1:8360 # 应该返回 HTMLwaline.你的域名),PHP 选「纯静态」walinehttp://127.0.0.1:8360$host1#PROXY-START/2
3location ^~ /4{5 # CORS 预检请求处理6 if ($request_method = 'OPTIONS') {7 add_header 'Access-Control-Allow-Origin' '$http_origin' always;8 add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS' always;9 add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type' always;10 add_header 'Access-Control-Max-Age' 1728000 always;11 add_header 'Content-Length' 0;12 return 204;13 }14
15 proxy_pass http://127.0.0.1:8360;16 proxy_set_header Host $host;17 proxy_set_header X-Real-IP $remote_addr;18 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;19 proxy_set_header X-Forwarded-Proto $scheme;20 proxy_set_header REMOTE-HOST $remote_addr;21 proxy_set_header Upgrade $http_upgrade;22 proxy_set_header Connection $connection_upgrade;23 proxy_http_version 1.1;24
25 add_header X-Cache $upstream_cache_status;26 add_header 'Access-Control-Allow-Origin' '$http_origin' always;27 add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,OPTIONS' always;28 add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type' always;29
30 set $static_filew6OwwKmG 0;31 if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )32 {33 set $static_filew6OwwKmG 1;34 expires 1m;35 }36 if ( $static_filew6OwwKmG = 0 )37 {38 add_header Cache-Control no-cache;39 }40}41
42#PROXY-END/保存后重载 Nginx:
1nginx -t && nginx -s reload站点设置 → SSL → Let’s Encrypt → 申请 → 勾选「强制 HTTPS」。
访问 https://waline.你的域名,确认:
1# 把备份脚本也恢复过去2chmod +x /opt/waline/backup.sh3
4# 替换 GitHub Token(如果需要)5vi /opt/waline/backup.sh6
7# 测试备份8/opt/waline/backup.sh9
10# 添加定时任务11(crontab -l 2>/dev/null; echo "0 3 * * * /opt/waline/backup.sh >> /opt/waline/backup/backup.log 2>&1") | crontab -如果你对 Linux 比较熟悉,可以把上面的步骤浓缩成几条命令:
1# 1. 安装 Docker2curl -fsSL https://get.docker.com | sh3systemctl start docker && systemctl enable docker4
5# 2. 拉取备份6mkdir -p /opt/waline7git clone https://TOKEN@github.com/USER/waline-backup.git /opt/waline/backup8
9# 3. 解压10cd /opt/waline11tar xzf backup/$(ls -t backup/waline-backup-*.tar.gz | head -1)12
13# 4. 启动14docker compose up -d15
16# 5. 恢复备份脚本和定时任务17chmod +x /opt/waline/backup.sh18(crontab -l 2>/dev/null; echo "0 3 * * * /opt/waline/backup.sh >> /opt/waline/backup/backup.log 2>&1") | crontab -然后去宝塔配 Nginx 和 SSL 就行。
💡 整个恢复过程大概 10-15 分钟,其中大部分时间花在等宝塔和 Docker 安装上。数据恢复本身只需要几秒钟。
服务器上的 Git 默认创建 master 分支,但 GitHub 新仓库默认是 main。脚本里加了 git branch -m master main 解决。如果已经初始化了 master,手动执行一下:
1cd /opt/waline/backup2git branch -m master main3git push -u origin mainToken 直接写在脚本里不是最佳实践,但因为脚本在自己服务器上、仓库是私有的,风险可控。如果介意,可以用环境变量或者 GitHub App 的方式认证。
| 位置 | 保留数量 | 说明 |
|---|---|---|
| 服务器本地 | 最近 7 份 | 节省磁盘空间 |
| GitHub 私有仓库 | 30 天 | 主备份,自动清理旧文件 |
| 手动备份 | 不定期 | 重大更新前手动备份一次 |
Waline 的数据就是一个 SQLite 文件,备份起来非常简单。与其依赖外部服务的免费额度,不如花 5 分钟写个脚本,数据掌握在自己手里才踏实。
脚本写好之后基本不用管,每天自动跑。偶尔去 GitHub 看一眼,确认备份在正常推送就行。
如果你喜欢,那么欢迎来到我的世界!
了解更多暂未播放



"所有的相遇都是久别重逢。"—— 未知


