Files
system-backu/README.md
T
Your Name e7fba5abe5 fix(storage): 修复存储目标编辑不显示配置 & 添加文件列表API
- fix(storage): StorageOut 增加 config 字段并解密返回,编辑时可回填
- fix(storage): Storage ORM 模型添加 config property 支持序列化
- fix(env): 修正 SECRET_KEY 截断、FERNET_KEY 非法占位符问题
- fix(deploy): 后端从 Docker 容器迁移到 systemd 服务,存储目标路径改为宿主机真实路径
- feat(api): 新增 GET /api/storages/{id}/files 文件浏览端点
- feat(frontend): 新增 listFiles API 调用
- docs: 更新 README 反映部署方式变更
2026-07-27 13:45:18 +08:00

147 lines
6.0 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.
# 数据备份管理系统
一个带 Web 操作界面的备份系统,支持将 **MySQL 数据库**、**服务器目录**、**InfluxDB**、**ETCD** 备份到 **本地目录****S3 兼容对象存储**AWS S3 / MinIO / Ceph)。支持手动触发、Cron 定时调度、备份保留策略,以及从备份还原。
## 功能
- 📦 **多数据源**MySQL 数据库(mysqldump)、服务器目录(tar.gz)、InfluxDB、ETCD
- ☁️ **多存储目标**:本地目录、S3 兼容对象存储
-**Cron 定时调度**:标准 5 段 cron 表达式
- 🔁 **备份还原**:从备份恢复 MySQL 库 / 解压目录
- 🗂️ **保留策略**:保留最近 N 个 + 保留 N 天
- 👤 **JWT 登录认证**RBAC 权限管理(admin/operator
- 📊 **运行历史与日志**:每次备份的执行详情、SHA256 校验、大小、耗时
- 🔐 **敏感字段加密**:密码、Token 在数据库中 Fernet 加密存储
- 📁 **文件浏览**:存储目标下的备份文件列表查看
## 技术栈
- **后端**Python 3.11、FastAPI、SQLAlchemy 2、APScheduler、aiofiles / aioboto3
- **前端**Vite + React 18 + TypeScript + Ant Design 5
- **数据库**SQLite(可平滑迁移 PostgreSQL
- **部署**:后端 systemd 服务 + 前端 Docker 容器(Nginx
## 架构
```
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ 浏览器 │────▶│ 前端容器 │────▶│ 后端服务 │
│ :5173 │ │ Nginx 反代 │ │ systemd :8765 │
└─────────────┘ └─────────────┘ └──────┬───────┘
┌─────────▼─────────┐
│ SQLite DB │
│ backup files (本地) │
└─────────────────────┘
```
## 部署方式
### 环境要求
- **后端**Python 3.11+(已在 `/root/system-backu/backend/venv` 中创建 venv
- **前端**:Docker(仅前端容器,运行于端口 5173)
- **依赖工具**`mysqldump`(备份 MySQL)、`etcdctl`(备份 ETCD)、`influx` CLI(备份 InfluxDB
### 1. 准备环境变量
```bash
cd /root/system-backu
cp .env.example .env
# 编辑 .env,至少设置以下三项:
# SECRET_KEY — openssl rand -hex 32
# FERNET_KEY — python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# INITIAL_ADMIN_PASSWORD — 管理员密码(登录后可通过页面修改)
```
### 2. 启动服务
**后端**systemd 托管,开机自启):
```bash
systemctl start backup-backend
systemctl enable backup-backend
journalctl -u backup-backend -f # 查看日志
```
**前端**Docker 容器):
```bash
cd /root/system-backu
docker compose up -d frontend
```
### 3. 访问
| 服务 | 地址 |
|------|------|
| 前端管理界面 | http://10.168.1.209:5173 |
| 后端 API | http://10.168.1.209:8765 |
| API 文档 | http://10.168.1.209:8765/docs |
### 4. 首次使用
1. 打开前端地址,用 `admin` / `INITIAL_ADMIN_PASSWORD` 登录(首次登录后建议修改密码)
2. **Storages** → 新建存储目标(本地路径建议用已映射到宿主机的目录)
3. **Jobs → 新建** → 选择数据源类型 → 填写源信息 → 选存储目标 → 保存
4. Job 列表点 **Run Now** 立即触发,或填写 `cron_expression` 启用定时调度
## 项目结构
```
.
├── docker-compose.yml # 仅前端容器
├── .env.example # 环境变量模板
├── backend/
│ ├── app/ # FastAPI 应用代码
│ │ ├── api/ # API 端点
│ │ ├── core/ # 核心逻辑(备份、存储、恢复)
│ │ ├── models/ # SQLAlchemy 模型
│ │ ├── schemas/ # Pydantic 数据模型
│ │ └── utils/ # 工具函数(加密等)
│ ├── alembic/ # 数据库迁移
│ └── venv/ # Python 虚拟环境(.gitignore
└── frontend/
├── src/ # React 源码
│ ├── pages/ # 页面组件
│ ├── api/ # API 调用
│ └── types/ # TypeScript 类型定义
└── nginx.conf # Nginx 反代配置
```
## 存储与持久化
- **数据库**`/root/system-backu/data/backend/backup.db`SQLite
- **备份文件**`/root/system-backu/data/backend/backups/`(按 任务名/日期/ 组织)
- **日志**`/root/system-backu/data/logs/`
所有数据均在宿主机上,**容器重启不会丢失**。备份文件通过文件系统直接访问和下载。
## API 概览
| 端点 | 说明 |
|------|------|
| `POST /api/auth/login` | 登录获取 JWT |
| `GET /api/storages` | 存储目标列表 |
| `POST /api/storages` | 创建存储目标 |
| `GET /api/storages/{id}/files` | 列出存储目标下的备份文件 |
| `POST /api/storages/{id}/test` | 测试存储目标连通性 |
| `GET /api/jobs` | 备份任务列表 |
| `POST /api/jobs` | 创建备份任务 |
| `POST /api/jobs/{id}/run` | 手动触发备份 |
| `GET /api/runs` | 运行历史 |
| `POST /api/restore` | 从备份恢复 |
完整 API 文档请访问 `/docs`
## 注意事项
- ⚠️ **单实例部署**:内置 APScheduler**不要启动多个 backend 进程**,否则出现重复调度
- 🔐 **敏感字段加密**:数据源密码、Token 在数据库中以 Fernet 加密,前端永远看不到明文(编辑时回显 `***`
- 💾 **存储目标路径**:本地存储的 path 必须是在宿主机上实际存在的目录,且后端进程有读写权限
- 🗄️ **mysqldump**:备份 MySQL 需要宿主机安装 `mysql-client`
## License
MIT