366 lines
14 KiB
Markdown
366 lines
14 KiB
Markdown
# AgentGIS Cloud Platform — 实际部署架构
|
||
|
||
> **本文档反映当前实际运行状态(2026-07-16 验证)。**
|
||
> 基于阿里云 ECS(39.107.238.22)+ 腾迅云 ECS(106.54.216.234)部署情况编写。
|
||
|
||
---
|
||
|
||
## 一、总体拓扑
|
||
|
||
```
|
||
用户
|
||
│
|
||
▼
|
||
Nginx Proxy Manager (mercator-npm) ← HTTPS 统一入口
|
||
│ ┌───────────────────────────────────────────┐
|
||
│ │ www.mercator.cn → homepage:3000 │
|
||
│ │ auth.mercator.cn → auth-front:3000 │
|
||
│ │ suites.mercator.cn → suite-front:3302 │
|
||
│ │ discussions.mercator.cn → discuss:3001 │
|
||
│ │ git.mercator.cn → gitea:3000 │
|
||
│ └───────────────────────────────────────────┘
|
||
│
|
||
├── mercator-homepage — 官网首页
|
||
├── mercator-auth-center-frontend — 认证前端 (Next.js)
|
||
├── mercator-auth-center-backend — 认证后端 (FastAPI, :8000)
|
||
├── mercator-suite-market-frontend — 套件市场前端 (Next.js)
|
||
├── suite-market — 套件市场后端 (FastAPI, :8001)
|
||
├── mercator-discussions-frontend — 讨论区前端 (Next.js)
|
||
├── mercator-discussions-backend — 讨论区后端 (FastAPI, :8005)
|
||
├── mercator-gitea — Gitea 代码托管 / Packages 存储
|
||
├── minio-nginx — MinIO 对象存储
|
||
├── mercator-postgres — PostgreSQL (统一元数据)
|
||
└── mercator-redis — Redis (缓存)
|
||
```
|
||
|
||
### 物理部署
|
||
|
||
| 服务器 | IP | 角色 | 运行内容 |
|
||
|--------|-----|------|---------|
|
||
| 阿里云 ECS | 39.107.238.22 | **生产环境** | 全部平台服务容器(Auth / Suite / Discussions / Gitea / 数据库) |
|
||
| 腾迅云 ECS | 106.54.216.234 | 备份 | Gitea(AgentGIS 组织) |
|
||
|
||
---
|
||
|
||
## 二、容器清单
|
||
|
||
### 2.1 认证中心 — Auth Center
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| **前端** | `mercator-auth-center-frontend:20260715a`,Next.js,端口 3000 |
|
||
| **后端** | `mercator-auth-center-backend:20260630h`,FastAPI,端口 8000 |
|
||
| **数据库** | `auth_center_db`(PostgreSQL) |
|
||
|
||
**后端 API:**
|
||
|
||
| 分组 | 路由 | 功能 |
|
||
|------|------|------|
|
||
| 公开认证 | `POST /api/v1/public/login/` | 密码登录 |
|
||
| | `POST /api/v1/public/mfa/verify-login/` | MFA 二次验证 |
|
||
| | `POST /api/v1/public/refresh/` | Token 刷新 |
|
||
| | `POST /api/v1/public/register/` | 注册 |
|
||
| | `POST /api/v1/public/forgot-password/` | 忘记密码 |
|
||
| | `POST /api/v1/public/reset-password/` | 重置密码 |
|
||
| 企业微信 OAuth | `GET /api/v1/public/oauth/wecom/qrcode/` | 扫码登录 |
|
||
| | `GET /api/v1/public/oauth/wecom/qrcode/status/{state}/` | 扫码状态轮询 |
|
||
| | `GET /api/v1/public/oauth/providers/` | 支持的 OAuth 提供商 |
|
||
| API Key | `POST/GET /api/v1/auth/api-keys/` | API Key 管理 |
|
||
| | `POST /api/v1/auth/api-keys/verify/` | API Key 校验 |
|
||
| 服务认证 | `POST /api/v1/service-auth/token/` | 服务账户 Token(HS256 JWT) |
|
||
| 用户管理 | `GET /api/v1/profile/me/` | 个人信息 |
|
||
| | `GET /api/v1/roles/me/` | 当前角色 |
|
||
| MFA | `GET /api/v1/mfa/status/` | MFA 状态 |
|
||
| | `POST /api/v1/mfa/totp/enable/` | 启用 TOTP |
|
||
| Session | `GET /api/v1/sessions/` | 会话列表 |
|
||
| OAuth2 服务端 | `GET /.well-known/openid-configuration` | OIDC 发现 |
|
||
| | `GET /.well-known/jwks.json` | JWKS |
|
||
| | `GET /oauth2/authorize/` | OAuth2 授权 |
|
||
| | `POST /oauth2/token` | Token 颁发 |
|
||
| 管理后台 | `GET /api/v1/admin/users/` | 用户管理 |
|
||
| 运维 | `GET /health` | 健康检查 |
|
||
| | `GET /health/detailed` | 详细健康状态 |
|
||
|
||
**数据库表(`auth_` 前缀):**
|
||
|
||
```
|
||
auth_users, auth_user_roles, auth_api_keys, auth_service_accounts,
|
||
auth_login_history, auth_audit_logs, auth_notifications,
|
||
auth_jwt_secrets, auth_jwt_secret_audit_log,
|
||
auth_email_verifications, auth_faqs, auth_system_configs,
|
||
auth_third_party_accounts,
|
||
oauth_clients, oauth_authorization_codes, oauth_refresh_tokens
|
||
```
|
||
|
||
### 2.2 套件市场 — Suite Market
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| **前端** | `mercator-suite-market-frontend:20260715a`,Next.js,端口 3302 |
|
||
| **后端** | `suite-market`(镜像 `mercator/suite-market-backend:20260630i`),FastAPI,端口 8001 |
|
||
| | 代码内标题为 "Scheduler Service",版本 2.3.9 |
|
||
| **数据库** | `suite_market_db`(PostgreSQL) |
|
||
|
||
**后端 API:**
|
||
|
||
| 分组 | 路由 | 功能 |
|
||
|------|------|------|
|
||
| 套件 CRUD | `GET /api/v1/suites` | 套件列表 |
|
||
| | `POST /api/v1/suites` | 创建套件 |
|
||
| | `GET /api/v1/suites/search?q=` | 搜索套件 |
|
||
| | `GET /api/v1/suites/{id}` | 套件详情 |
|
||
| | `PATCH /api/v1/suites/{id}` | 更新套件 |
|
||
| | `DELETE /api/v1/suites/{id}` | 删除套件 |
|
||
| | `POST /api/v1/suites/{id}/versions` | 发布版本 |
|
||
| | `POST /api/v1/suites/{id}/execute` | 执行套件 |
|
||
| 发布 | `POST /publish` | Git 仓库发布 |
|
||
| | `POST /publish/upload` | 文件上传发布 |
|
||
| 参数校验 | `POST /api/v1/parameters/validate` | 参数校验 |
|
||
| 合规检测 | `POST /api/v1/compliance/check` | 合规检测 |
|
||
| 类型 | `GET /api/v1/types` | 数据类型定义 |
|
||
| 分类 | `GET /api/v1/categories` | 分类列表 |
|
||
| 用户 | `POST /api/v1/users` | 创建用户 |
|
||
| | `POST /api/v1/users/apply-developer` | 申请开发者 |
|
||
| 管理 | `GET /api/v1/admin/...` | 管理员接口 |
|
||
| 配置 | `GET /api/v1/config` | 系统配置 |
|
||
| 健康 | `GET /api/v1/health` | 健康检查 |
|
||
|
||
**数据库表(`suite_` 前缀):**
|
||
|
||
```
|
||
suite_suites — 套件主表
|
||
suite_versions — 版本记录
|
||
suite_categories — 分类
|
||
suite_executions — 执行记录
|
||
suite_user_roles — 用户角色
|
||
suite_developer_applications — 开发者申请
|
||
suite_business_types — 业务类型
|
||
suite_data_types — 数据类型
|
||
suite_file_type_mappings — 文件类型映射
|
||
```
|
||
|
||
**后端内部模块:**
|
||
|
||
| 模块 | 文件 | 功能 |
|
||
|------|------|------|
|
||
| Workflow 引擎 | `services/workflow.py` | DAG 拓扑排序,`$steps.xxx.yyy` / `$inputs.xxx` 参数解析,节点执行 |
|
||
| 合规检测 | `services/compliance.py` + `routers/compliance.py` | 仅基础格式检查(params_schema/steps/exists),无代码安全审计 |
|
||
| 参数解析 | `services/param_resolver.py` | 参数引用解析(`$steps.xxx` / `$inputs.xxx`) |
|
||
| 任务队列 | `services/queue.py` | 简化版任务记录(内存存储,无 Redis Worker) |
|
||
| 角色守卫 | `services/role_guard.py` | 角色权限控制 |
|
||
| 认证守卫 | `auth_guard.py` | JWT / API Key 认证中间件 |
|
||
|
||
**关于 Skills 层:** 架构文档中规划的独立 Skills 微服务已被移除。旧表 `suite_skills` 和 `scripts` 已在迁移中删除。技能注册在发布流程中自动完成,不独立暴露 API。
|
||
|
||
### 2.3 讨论区 — Discussions
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| **前端** | `mercator-discussions-frontend:20260630q`,Next.js,端口 3001 |
|
||
| **后端** | `mercator-discussions-backend:20260715a`,FastAPI,端口 8005 |
|
||
| **数据库** | `discussions_db`(PostgreSQL) |
|
||
|
||
**后端 API:**
|
||
|
||
| 路由 | 方法 | 功能 |
|
||
|------|------|------|
|
||
| `/api/v1/topics` | GET | 话题列表 |
|
||
| `/api/v1/topics` | POST | 创建话题 |
|
||
| `/api/v1/topics/{id}` | GET | 话题详情 |
|
||
| `/api/v1/topics/{id}` | PATCH | 更新话题 |
|
||
| `/api/v1/topics/{id}` | DELETE | 删除话题 |
|
||
| `/api/v1/topics/{id}/close` | POST | 关闭话题 |
|
||
| `/api/v1/topics/{id}/reopen` | POST | 重新打开话题 |
|
||
| `/api/v1/topics/{topic_id}/comments` | GET | 评论列表 |
|
||
| `/api/v1/topics/{topic_id}/comments` | POST | 发表评论 |
|
||
| `/api/v1/comments/{comment_id}` | PATCH | 编辑评论 |
|
||
| `/api/v1/comments/{comment_id}` | DELETE | 删除评论 |
|
||
| `/api/v1/labels` | GET | 标签列表 |
|
||
| `/api/v1/labels` | POST | 创建标签 |
|
||
|
||
**种子标签:** bug (#ef4444), feature (#22c55e), question (#3b82f6), discussion (#a855f7), announcement (#f59e0b), suggestion (#06b6d4)
|
||
|
||
**数据库表(`discussions_` 前缀):**
|
||
|
||
```
|
||
discussions_topics — 话题
|
||
discussions_comments — 评论
|
||
discussions_labels — 标签
|
||
discussions_topic_labels — 话题-标签关联
|
||
```
|
||
|
||
### 2.4 Gitea
|
||
|
||
| 实例 | 域名 | 用途 | 部署位置 |
|
||
|------|------|------|---------|
|
||
| SuiteHub | `git.mercator.cn` | 平台仓库 + Packages(镜像/脚本包分发) | 阿里云 ECS |
|
||
| AgentGIS | `gitea.mercator.cn` | AgentGIS 组织项目仓库 | 腾迅云 ECS |
|
||
|
||
**Gitea Packages 用途:**
|
||
- OCI Registry:基础镜像存储与分发(`docker pull`)
|
||
- Generic Packages:脚本包存储与分发(Publish API 自动上传)
|
||
|
||
### 2.5 基础设施
|
||
|
||
| 服务 | 容器 | 版本 |
|
||
|------|------|------|
|
||
| PostgreSQL | mercator-postgres | postgres:16-alpine |
|
||
| Redis | mercator-redis | redis:7-alpine |
|
||
| NPM | mercator-npm | jc21/nginx-proxy-manager:latest |
|
||
| MinIO | minio-nginx | nginx:alpine(MinIO 反代,端口 9000) |
|
||
|
||
---
|
||
|
||
## 三、认证体系
|
||
|
||
### 3.1 凭证类型
|
||
|
||
| 类型 | 获取方式 | 有效期 | 使用场景 |
|
||
|------|---------|--------|---------|
|
||
| **JWT (Access Token)** | 密码登录 / 企业微信扫码 | 15 分钟 | 浏览器 Web UI |
|
||
| **API Key (`mk_`)** | Auth Center Dashboard 创建 | 自定义(默认 90 天) | AI Agent 自动化调用 |
|
||
| **服务账户 Token (HS256 JWT)** | `POST /api/v1/service-auth/token/` | 1 小时 | 微服务间内部通信 |
|
||
| **Gitea Token** | Gitea 设置页面生成 | 自定义 | Publish API 上传脚本包 |
|
||
|
||
### 3.2 认证流程
|
||
|
||
```
|
||
用户浏览器 → auth.mercator.cn
|
||
├── 密码登录 → JWT
|
||
├── 企业微信扫码 → OIDC → JWT
|
||
└── MFA (TOTP) 二次验证
|
||
|
||
AI Agent (OpenClaw) → API Key (mk_...) → suite-market API
|
||
|
||
微服务通信 → HS256 JWT (1h) → Auth Center 签发
|
||
```
|
||
|
||
### 3.3 OAuth2 / OIDC 支持
|
||
|
||
Auth Center 内置 OAuth2 服务端,支持:
|
||
- 企业微信作为 OIDC 身份源
|
||
- 自签发 RS256 签名的 JWT(通过 `/.well-known/jwks.json` 暴露公钥)
|
||
- 设备授权流程(OAuth 2.0 Device Code)
|
||
|
||
---
|
||
|
||
## 四、套件发布与执行
|
||
|
||
### 4.1 发布流程
|
||
|
||
```
|
||
开发者上传 zip/tgz 包 → POST /publish 或 POST /publish/upload
|
||
│
|
||
┌────┴────┐
|
||
│ 解析 workflow.yaml
|
||
│ 合规检测 (compliance)
|
||
│ 参数校验 (parameters)
|
||
│ 打包 scripts/ → .tar.gz
|
||
│ 上传至 Gitea Packages
|
||
│ 注册版本至 suite_versions
|
||
└─────────┬──┘
|
||
│
|
||
返回发布结果
|
||
```
|
||
|
||
发布入口:`suites.mercator.cn/publish`
|
||
|
||
### 4.2 任务执行
|
||
|
||
**当前简化实现:** 任务队列是本地内存记录(`services/queue.py`),没有常驻 Worker 进程。
|
||
任务创建后返回 `task_id`,由调用方通过 GIS Actions 本地执行。
|
||
|
||
**预期完整流程(待 GIS Actions 实现):**
|
||
|
||
```
|
||
AI Agent 下发任务 → POST /api/v1/suites/{id}/execute
|
||
│
|
||
▼
|
||
GIS Actions 拉取任务 → 下载脚本包 → docker run 执行 → 回传结果
|
||
```
|
||
|
||
### 4.3 基础镜像
|
||
|
||
```
|
||
gis-base:latest
|
||
├── Linux OS (Debian/Ubuntu slim)
|
||
├── Python 3.11
|
||
├── GDAL, Shapely, GeoPandas, Fiona, PyProj, Rasterio
|
||
└── 入口脚本 run.sh
|
||
```
|
||
|
||
基础镜像存储在 Gitea Packages(OCI Registry),由管理员构建维护。
|
||
|
||
---
|
||
|
||
## 五、数据库概览
|
||
|
||
### 5.1 数据库分布
|
||
|
||
| 数据库 | 用途 | 表前缀 |
|
||
|--------|------|--------|
|
||
| `gitea_db` | Gitea 元数据 | Gitea 自有 |
|
||
| `auth_center_db` | 认证、用户、API Key、MFA、OAuth、审计 | `auth_`、`oauth_` |
|
||
| `suite_market_db` | 套件、版本、执行记录、分类 | `suite_` |
|
||
| `discussions_db` | 话题、评论、标签 | `discussions_` |
|
||
|
||
### 5.2 跨服务数据共享
|
||
|
||
Auth Center 与 Suite Market / Discussions 通过 API 调用互通:
|
||
- Suite Market 调用 Auth Center 验证 JWT / API Key
|
||
- Discussions 调用 Auth Center 验证用户身份
|
||
- 各服务通过 `DATABASE_URL` 连接各自的数据库
|
||
|
||
---
|
||
|
||
## 六、安全防护(当前实现)
|
||
|
||
| 层面 | 措施 |
|
||
|------|------|
|
||
| 认证 | JWT 15m + API Key + 服务账户 Token 三级凭证 |
|
||
| 速率限制 | `slowapi` 限流,全局速率控制 |
|
||
| CSRF | `fastapi-csrf-protect`(Auth Center) |
|
||
| CORS | 全部服务设置 `allow_origins=["*"]`(NPM 层控制) |
|
||
| 密码 | 支持 MFA TOTP 二次验证 |
|
||
| 日志 | 操作审计日志 (`auth_audit_logs`) |
|
||
| 镜像 | Gitea Packages 私有 Registry,需认证拉取 |
|
||
|
||
**尚未实现的规划项:** 脚本包内存擦除、反调试探针、数字水印、强制心跳校验(标注在旧架构文档中,待 GIS Actions 实现时同步落地)。
|
||
|
||
---
|
||
|
||
## 七、当前的架构缺口 / 待办
|
||
|
||
| 缺口 | 影响 | 优先级 |
|
||
|------|------|--------|
|
||
| **用户反馈通道缺失** | 本地使用套件出问题,没有渠道报给开发者 | 高 |
|
||
| **未验证 GIS Actions 就绪状态** | 套件市场已上线,但 GIS Actions(本地执行器)的发布通道、用户安装流程未验证 | 中
|
||
| **无任务 Worker** | 队列只有内存记录,没有实际调度执行 | 中 |
|
||
| **合规检测基本是空壳** | 仅检查 params_schema/output_schema/steps 格式,不扫代码、不验引用(系统中已无独立的 skill 概念) | 中 |
|
||
| **无监控告警** | 服务挂了没人知道 | 中 |
|
||
| **脚本清理未落地** | 知识产权保护机制待实现 | 低(GIS Actions 未跑之前无需) |
|
||
|
||
---
|
||
|
||
## 八、技术栈总览
|
||
|
||
| 层级 | 技术选型 |
|
||
|------|---------|
|
||
| 前端框架 | Next.js(全部前端) |
|
||
| 后端框架 | FastAPI(全部后端) |
|
||
| 数据库 | PostgreSQL 16 |
|
||
| 缓存 | Redis 7 |
|
||
| 反向代理 | Nginx Proxy Manager (jc21/nginx-proxy-manager) |
|
||
| OIDC 身份源 | 企业微信 |
|
||
| Token 签名 | RS256 (OIDC) / HS256 (服务内部) |
|
||
| 代码托管 | Gitea |
|
||
| 镜像仓库 | Gitea Packages (OCI) |
|
||
| 脚本包存储 | Gitea Generic Packages |
|
||
| 对象存储 | MinIO |
|
||
| 容器管理 | Docker (原生,非编排) |
|
||
| 邮件推送 | 阿里云 DirectMail |
|
||
|
||
---
|
||
|
||
*本文档反映 2026-07-16 实际部署状态。随平台演进持续更新。*
|