chore: 忽略离线部署包,提交安全加固、数据库初始化与文档

- .gitignore: 忽略 docker/offline 离线部署包(镜像/运行时等大文件)
- 安全加固: 新增 compute/api/security.py 及各端安全测试,补充 docs/security-hardening.md
- 数据库: 新增完整初始化 SQL 与 docs/database-config.md
- 数据转换与评测: 修复类型检查、增强校验并补充测试
- Docker 配置与环境变量更新

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
wuyongtao
2026-08-07 09:24:35 +08:00
parent e397bcc2ca
commit 75cc105ebc
24 changed files with 1850 additions and 50 deletions

164
docs/database-config.md Normal file
View File

@@ -0,0 +1,164 @@
# 数据库配置与初始化说明PostgreSQL / Redis
> 记录平台的 **PostgreSQL 账号密码**、**Redis 账号密码**、**数据库地址在代码中的配置位置**
> 以及**切换 PG 数据集时如何执行完整初始化 SQL**。
---
## 1. 账号密码速查表
### 1.1 PostgreSQL
| 环境 | 地址 | 用户 | 密码 | 数据库 | 来源 |
|------|------|------|------|--------|------|
| 代码默认值 | `localhost:15432` | `yg_ft` | `change_me` | `yg_ft` | `config.py` / `session.py``DATABASE_URL` 兜底 |
| Docker 部署 | `www.caoxiaozhu.com:5432` | `root` | `8811614287327Leo` | `yg_ft` | `docker/app/.env``DATABASE_URL` |
| Docker 内置 Postgres已注释 | `localhost:15432` | `root` | `8811614287327Leo` | `yg_ft` | `docker/app/docker-compose.yml` 注释掉的 postgres 服务 |
> ⚠️ `change_me` 与 `8811614287327Leo` 均为默认/示例凭据,生产环境务必更换。
### 1.2 Redis
| 项 | 值 | 说明 |
|----|-----|------|
| 连接串 | `redis://:<REDIS_PASSWORD>@redis:6379/0` | 已内嵌密码docker 网络内服务名 `redis`,端口 6379db 0 |
| 对外端口 | `16379``REDIS_PORT` | 宿主机映射 |
| 密码 | `docker/app/.env``REDIS_PASSWORD` | 已启用 `requirepass` 鉴权 |
| 镜像 | `redis:7-alpine` | 已开启 AOF`--appendonly yes`+ `requirepass` |
> **当前后端代码未使用 Redis**`redis` 包已列入 `requirements.txt``REDIS_URL` 通过
> docker-compose 注入容器,但全仓库 `backend/`、`compute/` 没有任何 `import redis` /
> `Redis(...)` 连接代码。Redis 为后续功能预留;**即便如此仍已配置鉴权**
> 避免无密码实例对外暴露(纵深防御)。未来启用时按 `REDIS_URL` 连接即可。
>
> 健康检查通过容器环境变量 `REDISCLI_AUTH` 认证,不在进程参数中泄露密码。
---
## 2. 数据库地址在代码中的配置位置
### 2.1 后端backend
| 文件 | 作用 | 取值 |
|------|------|------|
| `backend/app/core/config.py` | **唯一权威配置**`Settings.database_url` | `os.getenv("DATABASE_URL", "postgresql+psycopg://yg_ft:change_me@localhost:15432/yg_ft")` |
| `backend/app/db/session.py` | SQLAlchemy 引擎(`get_db` / `session_scope` | `os.getenv("DATABASE_URL", ...)` 同样兜底 |
| `backend/app/db/platform_store.py` | **平台主存储**,直接用 psycopg 连接池 | 取 `settings.database_url``_psycopg_url()``postgresql+psycopg://` 转成 `postgresql://` |
| `backend/app/modules/data_process/store.py` | 数据处理存储 | `get_settings().database_url` |
> **环境变量加载顺序**`config.py` 导入时会 `load_dotenv(backend/.env, override=True)`
> 即 **`backend/.env` 会覆盖系统环境变量**docker 部署则直接由 compose 注入 `DATABASE_URL`。
> 最终优先级:`backend/.env` / compose 注入的环境变量 > 代码内默认值。
### 2.2 部署配置docker
| 文件 | 关键项 |
|------|--------|
| `docker/app/.env` | `DATABASE_URL``POSTGRES_USER``POSTGRES_PASSWORD``REDIS_URL``REDIS_PORT` |
| `docker/app/docker-compose.yml` | `backend-api` 环境透传上述变量;`redis` 服务定义 |
```ini
# docker/app/.env节选
DATABASE_URL=postgresql+psycopg://root:8811614287327Leo@www.caoxiaozhu.com:5432/yg_ft
POSTGRES_USER=root
POSTGRES_PASSWORD=8811614287327Leo
REDIS_PASSWORD=<强密码> # Redis requirepass新增鉴权
REDIS_URL=redis://:<REDIS_PASSWORD>@redis:6379/0 # 连接串内嵌密码
REDIS_PORT=16379
USE_BUILTIN_POSTGRES=false # 当前用共享外部库,内置 postgres 服务被注释
USE_BUILTIN_REDIS=true # Redis 用内置服务
```
---
## 3. 完整初始化 SQL
### 3.1 脚本位置
| 脚本 | 用途 |
|------|------|
| **`backend/app/db/sql/000_full_init.sql`** | **一键初始化脚本(新增)**:建库表 + 索引 + 种子数据,幂等,覆盖全部 39 张运行表 |
| `backend/app/db/sql/001_platform_runtime.sql` | 平台核心表(应用启动自动执行) |
| `backend/app/db/sql/002_governance.sql` | 治理表(应用启动自动执行) |
| `backend/app/db/sql/003_tenant_quota.sql` | 租户配额列(应用启动自动执行) |
| `backend/app/db/sql/003_model_path_governance.sql` | 模型可训练列(**应用不自动执行**,已并入完整脚本) |
| `backend/app/db/sql/002_data_process.sql` | 数据处理表(**应用不自动执行**,已并入完整脚本) |
| `docs/postgres-schema.sql` | ⚠️ **目标设计稿**UUID/JSONB与运行时代码不兼容**不要用于初始化** |
> **重要**`docs/postgres-schema.sql` 是规划中的“目标 schema”UUID 主键、`ft_platform` schema 等),
> 运行时代码明确拒绝该结构(`002_data_process.sql` 检测到 `datasets.id` 非 TEXT 会直接报错)。
> 初始化请使用 **`000_full_init.sql`**。
### 3.2 执行步骤(全新 PG 环境)
**第 1 步:创建角色与数据库**(必须单独执行,不能放进事务)
```sql
-- 以超级用户(如 postgres连接
CREATE ROLE yg_ft LOGIN PASSWORD '请改为强密码';
CREATE DATABASE yg_ft OWNER yg_ft;
-- 如需应用执行 CREATE EXTENSION 等,可再授予超级用户(按需):
-- ALTER ROLE yg_ft SUPERUSER;
```
**第 2 步:执行完整初始化脚本**
```bash
psql "postgresql://yg_ft:密码@<host>:5432/yg_ft" \
-f backend/app/db/sql/000_full_init.sql
```
脚本特点:
- 全程一个事务(`BEGIN; ... COMMIT;`),失败自动回滚
- 所有 DDL 使用 `IF NOT EXISTS` / `ADD COLUMN IF NOT EXISTS`**可重复执行**
-`DO $$...$$` 语句块,必须用 `psql` 执行(应用内部的按分号切分 `executescript()` 不适用)
- 自动写入种子用户:`admin / admin123``operator / operator123`(登录后请改密)
**第 3 步:校验**
```sql
SELECT count(*) FROM pg_tables WHERE schemaname = 'public'; -- 应 ≥ 39
SELECT username, role, status FROM users; -- 应有 admin / operator
```
### 3.3 执行方式对比(三种途径)
| 方式 | 覆盖范围 | 命令 |
|------|----------|------|
| **A. 完整脚本(推荐,切换新库)** | 全部 39 表 + 索引 + 种子 | `psql ... -f 000_full_init.sql` |
| B. 应用自动初始化 | 001 + 002_governance + 003_tenant_quota + 种子用户;**不含**数据处理表、`models.can_train``data_convert_tasks` | 应用首次调用 `get_platform_store()``ensure_schema()` 自动执行 |
| C. 数据处理表单独安装 | `002_data_process.sql` 全部内容 | 在 `backend/` 目录下:`python -m app.modules.data_process.schema_cli --apply --yes`(或 `--check` 只读检查) |
> **缺口说明**
> - `models.can_train`(训练预检用)只在 `003_model_path_governance.sql` 中创建,应用启动**不会**自动执行;
> - `data_convert_tasks`(数据转换任务表)运行时代码引用但**原 SQL 脚本缺失**
> 已统一并入 `000_full_init.sql` 补齐。若现有库缺这两项,执行一次完整脚本即可幂等补上。
### 3.4 完整脚本包含的表39 张)
**核心**users、models、trained_models、model_lineage、model_artifacts、model_export_jobs、
datasets、dataset_files、compute_nodes、gpus、fine_tune_tasks、fine_tune_metrics、
fine_tune_checkpoints、compute_jobs、gpu_allocations、scheduler_locks、resource_replicas、
resource_sync_jobs、eval_tasks、eval_dimensions、compare_tasks、projects、project_members、
roles、sessions、acls
**治理**tenants、approval_templates、approval_instances、approval_steps、audit_logs、retention_policies
**数据处理**data_process_tasks、data_process_source_files、data_process_preview_items、
data_process_results、dataset_file_versions、dataset_records
**数据转换**data_convert_tasks新增补齐
---
## 4. 安全注意事项
1. **更换默认密码**`change_me`(代码兜底)、`8811614287327Leo`(部署)、`admin123`/`operator123`(种子用户)、`REDIS_PASSWORD` 上线前必须更换。
2. **Redis 已加鉴权**:已配置 `requirepass` + `REDISCLI_AUTH` 健康检查;`REDIS_URL` 内嵌密码。若端口需暴露公网,仍建议用防火墙/安全组限制来源。
3. **`docker/*/.env` 已入库,含明文凭据**
- `backend/.env` 已被 `.gitignore` 排除;
-`docker/app/.env``docker/compute/.env` 目前被 git 跟踪(`git ls-files` 可见),
其中的 `DATABASE_URL``POSTGRES_PASSWORD``COMPUTE_SERVICE_TOKEN` 等均为明文。
- **建议**:轮换这些凭据,将 `docker/*/.env` 移出版本库(`git rm --cached`)并改用
部署侧机密注入(如 docker secrets / CI 变量 / 环境变量模板),保留 `.env.example` 作为模板。
4. **最小权限**:应用角色只需对业务库的 DML/DDL 权限,尽量避免 SUPERUSER。