Files
termi-blog/deploy/docker/BACKUP_AND_RECOVERY.md

149 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 备份与恢复说明
这套博客现在已经有:
- PostgreSQL 数据库
- Markdown 原文内容
- 媒体文件 / 对象存储
- 版本历史 / 审计日志 / 订阅数据
所以生产上最重要的不是再多一两个功能,而是**出事后能不能快速恢复**。
## 1. 建议的最小备份策略
### PostgreSQL
- **频率**:每天至少 1 次;高频站点建议每 6~12 小时 1 次
- **工具**`pg_dump --format=custom`
- **脚本**`deploy/scripts/backup/backup-postgres.sh`
### Markdown 原文
- **频率**:每次发布后 + 每天定时 1 次
- **脚本**`deploy/scripts/backup/backup-markdown.sh`
- **原因**Markdown 是内容源,恢复速度最快
### 媒体文件
- 如果是本地目录:打包归档
- 如果是 R2 / S3 / MinIO定时 `aws s3 sync`
- **脚本**`deploy/scripts/backup/backup-media.sh`
## 2. 一键脚本
```bash
# 全量备份
./deploy/scripts/backup/backup-all.sh
# 单独备份数据库
DATABASE_URL=postgres://... ./deploy/scripts/backup/backup-postgres.sh
# 单独备份 Markdown
MARKDOWN_SOURCE_DIR=./backend/content/posts ./deploy/scripts/backup/backup-markdown.sh
# 单独备份媒体(本地目录)
MEDIA_SOURCE_DIR=./uploads ./deploy/scripts/backup/backup-media.sh
# 单独备份媒体R2 / S3
MEDIA_S3_SOURCE=s3://bucket-name ./deploy/scripts/backup/backup-media.sh
```
## 3. 恢复步骤
### 恢复 PostgreSQL
```bash
DATABASE_URL=postgres://... ./deploy/scripts/backup/restore-postgres.sh ./backups/postgres/latest.dump
```
### 恢复 Markdown
```bash
MARKDOWN_TARGET_DIR=./backend/content/posts ./deploy/scripts/backup/restore-markdown.sh ./backups/markdown/latest.tar.gz
```
### 恢复媒体
```bash
# 本地目录方式
MEDIA_TARGET_DIR=./uploads ./deploy/scripts/backup/restore-media.sh ./backups/media/latest.tar.gz
# R2 / S3 方式
MEDIA_S3_TARGET=s3://bucket-name ./deploy/scripts/backup/restore-media.sh ./backups/media/media-20260331T120000Z
```
## 4. 推荐的生产 Cron 示例
```cron
# 每天 03:10 备份 PostgreSQL
10 3 * * * cd /opt/termi-astro && DATABASE_URL=postgres://... ./deploy/scripts/backup/backup-postgres.sh >> /var/log/termi-backup.log 2>&1
# 每天 03:25 备份 Markdown
25 3 * * * cd /opt/termi-astro && MARKDOWN_SOURCE_DIR=./backend/content/posts ./deploy/scripts/backup/backup-markdown.sh >> /var/log/termi-backup.log 2>&1
# 每天 03:40 备份媒体
40 3 * * * cd /opt/termi-astro && MEDIA_S3_SOURCE=s3://bucket-name ./deploy/scripts/backup/backup-media.sh >> /var/log/termi-backup.log 2>&1
# 每天 04:15 清理过期备份
15 4 * * * cd /opt/termi-astro && ./deploy/scripts/backup/prune-backups.sh >> /var/log/termi-backup.log 2>&1
# 每天 04:40 异地同步
40 4 * * * cd /opt/termi-astro && OFFSITE_TARGET=/mnt/offsite/termi-astro-backups ./deploy/scripts/backup/sync-backups-offsite.sh >> /var/log/termi-backup.log 2>&1
```
## 5. 建议你们再加一层异地备份
仅仅把备份留在同一台服务器上不够。
至少保证:
- 主机本地保留最近 7~14 天
- 再同步一份到另一块存储 / 另一台主机 / 对象存储冷备桶
## 6. 恢复演练建议
建议每个月至少做 1 次演练:
1. 用最新数据库备份恢复到临时环境
2. 用 Markdown 备份恢复内容目录
3. 用媒体备份恢复对象
4. 校验:
- 首页可打开
- 文章详情可打开
- 图片可访问
- 后台可登录
- 审计 / 版本 / 订阅表存在数据
也可以直接用恢复演练脚本:
```bash
DATABASE_URL=postgres://... \
POSTGRES_BACKUP=./backups/postgres/latest.dump \
MARKDOWN_BACKUP=./backups/markdown/latest.tar.gz \
MEDIA_BACKUP=./backups/media/latest.tar.gz \
./deploy/scripts/backup/verify-restore.sh
```
## 7. 当前架构下的恢复优先级
发生事故时建议按这个顺序:
1. 恢复数据库
2. 恢复 Markdown 原文
3. 恢复媒体资源
4. 启动 backend / frontend / admin
5. 进入后台检查:
- 审计日志
- 文章版本历史
- 订阅目标与最近投递
## 8. 说明
这些脚本是**仓库内参考实现**,没有在你们生产机上自动执行。
正式上线前请按你们实际目录、R2/S3 桶、数据库连接串、cron 规范再过一遍。
另外仓库里已经提供:
- `deploy/systemd/README.md`
- `deploy/systemd/termi-backup-all.timer`
- `deploy/systemd/termi-backup-prune.timer`
- `deploy/systemd/termi-backup-offsite-sync.timer`
如果宿主机使用 systemd建议优先启用 timer而不是只靠手工执行。