# 数据备份管理系统 一个带 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