ci: 修复数据库备份 workflow——改用 mac runner、EC2 端读密码、本机落盘、每日定时

backup.yml 原 runs-on ubuntu-latest 无对应 runner、落盘 NAS 路径在 mac runner 不存在,长期跑不起来。
改为 runs-on mac + scripts/ci/backup-db.sh:复用 lib-forgejo 的 ssh 封装连 EC2,
在 EC2 端从 production.env 读 DSN 密码 mysqldump(零额外 secret),流回本机 ~/jiu-db-backups
gzip 落盘、保留 30 天、完整性校验,恢复每日 02:00 定时 + Telegram 成败通知。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YZ4DskSRKsSiheQonFtQvx
This commit is contained in:
wangjia
2026-06-21 11:39:28 +08:00
parent 1a1d9aa15e
commit b42a70ff3b
2 changed files with 62 additions and 23 deletions
+21 -23
View File
@@ -1,37 +1,35 @@
name: DB Backup
on:
# 定时备份已暂停(保留手动触发)。恢复时取消下面 schedule 的注释即可。
# schedule:
# - cron: '0 18 * * *' # UTC 18:00 = 北京时间 02:00
# 每日定时备份(北京时间 02:00)。手动触发亦可。
schedule:
- cron: '0 18 * * *' # UTC 18:00 = 北京时间 02:00
workflow_dispatch:
concurrency:
group: db-backup
cancel-in-progress: false
jobs:
backup:
runs-on: ubuntu-latest
runs-on: mac
steps:
- name: Setup SSH
run: |
mkdir -p ~/.ssh
printf '%s' "${{ secrets.EC2_SSH_KEY }}" > ~/.ssh/ec2.pem
chmod 600 ~/.ssh/ec2.pem
ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts
- uses: actions/checkout@v4
- name: Dump MySQL to NAS
- name: Dump MySQL to local backup dir
env:
EC2_SSH_KEY: ${{ secrets.EC2_SSH_KEY }}
EC2_HOST: ${{ secrets.EC2_HOST }}
EC2_USER: ${{ secrets.EC2_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
BACKUP_DIR=/volume1/docker/backups/jiu-db
mkdir -p $BACKUP_DIR
FILENAME="jiu_db_$(date +%Y%m%d_%H%M%S).sql.gz"
ssh -i ~/.ssh/ec2.pem ${EC2_USER}@${EC2_HOST} \
"docker exec jiu_mysql mysqldump -uroot -p${DB_PASSWORD} jiu_db" \
| gzip > ${BACKUP_DIR}/${FILENAME}
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
echo "Saved: ${BACKUP_DIR}/${FILENAME}"
run: sh scripts/ci/backup-db.sh
- name: Cleanup SSH key
- name: Notify (Telegram)
if: always()
run: rm -f ~/.ssh/ec2.pem
env:
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
run: |
if [ "${{ job.status }}" = "success" ]; then ICON="✅"; LABEL="数据库备份成功"; else ICON="❌"; LABEL="数据库备份失败"; fi
curl -f -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
-d "chat_id=${TELEGRAM_CHAT_ID}" \
--data-urlencode "text=${ICON} 岩美 ${LABEL}" > /dev/null || true