256 lines
8.4 KiB
Markdown
256 lines
8.4 KiB
Markdown
# 动态路由与Nginx自动化配置 Spec
|
||
|
||
## Why
|
||
当前系统为每个项目分配独立端口(9000-9100),存在以下问题:
|
||
1. 服务器防火墙需要开放大量端口
|
||
2. URL不够友好(需要带端口号)
|
||
3. 手动配置Nginx反向代理繁琐
|
||
|
||
通过动态路由+Nginx自动化配置,可以实现:
|
||
- 所有项目共用单一端口(80/443)
|
||
- 友好的URL路径(如 `/project/{id}/`)
|
||
- 自动化Nginx配置更新,无需手动干预
|
||
|
||
## What Changes
|
||
- **新增** Nginx配置管理服务
|
||
- **新增** Nginx配置模板系统
|
||
- **修改** 项目访问方式从多端口改为动态路由
|
||
- **修改** processManager 启动逻辑,使用固定内部端口
|
||
- **新增** Nginx配置自动重载机制
|
||
- **新增** 本地开发模式支持(可选安装Nginx)
|
||
|
||
## Impact
|
||
- Affected specs: 项目部署流程、URL生成规则、端口管理
|
||
- Affected code:
|
||
- `server/services/processManager.js`
|
||
- `server/services/projectService.js`
|
||
- `server/config/index.js`
|
||
- 新增 `server/services/nginxManager.js`
|
||
- 新增 `server/templates/nginx/` 配置模板
|
||
|
||
## ADDED Requirements
|
||
|
||
### Requirement: Nginx配置管理服务
|
||
系统 SHALL 提供Nginx配置管理服务,支持自动生成和更新Nginx配置。
|
||
|
||
#### Scenario: 创建项目时生成Nginx配置
|
||
- **WHEN** 用户创建新项目
|
||
- **THEN** 系统自动为该项目生成Nginx location配置块
|
||
- **AND** 配置文件保存到指定目录
|
||
- **AND** 自动重载Nginx使配置生效
|
||
|
||
#### Scenario: 删除项目时清理Nginx配置
|
||
- **WHEN** 用户删除项目
|
||
- **THEN** 系统自动移除该项目的Nginx配置
|
||
- **AND** 自动重载Nginx使配置生效
|
||
|
||
#### Scenario: 启动项目时更新upstream
|
||
- **WHEN** 项目启动成功
|
||
- **THEN** 系统更新Nginx upstream配置指向正确的内部端口
|
||
- **AND** 自动重载Nginx使配置生效
|
||
|
||
### Requirement: 动态路由访问
|
||
系统 SHALL 通过动态路由路径访问不同项目,而非独立端口。
|
||
|
||
#### Scenario: 访问项目
|
||
- **WHEN** 用户访问 `/project/{projectId}/`
|
||
- **THEN** Nginx将请求代理到对应项目的内部服务
|
||
- **AND** 项目内部服务运行在固定内部端口范围(如127.0.0.1:9000-9100)
|
||
|
||
#### Scenario: 生成项目URL
|
||
- **WHEN** 项目启动成功
|
||
- **THEN** 系统生成格式为 `{BASE_URL}/project/{projectId}/` 的访问地址
|
||
- **AND** 不再包含端口号
|
||
|
||
### Requirement: 本地开发模式支持
|
||
系统 SHALL 支持本地开发环境,可选择是否使用Nginx。
|
||
|
||
#### Scenario: 本地无Nginx环境
|
||
- **WHEN** 系统检测到本地未安装或未配置Nginx
|
||
- **THEN** 系统回退到原有的多端口模式
|
||
- **AND** 在日志中提示可安装Nginx获得更好体验
|
||
|
||
#### Scenario: 本地有Nginx环境
|
||
- **WHEN** 系统检测到本地已安装Nginx
|
||
- **THEN** 系统使用动态路由模式
|
||
- **AND** 自动配置Nginx
|
||
|
||
### Requirement: Nginx配置模板
|
||
系统 SHALL 使用模板化方式管理Nginx配置。
|
||
|
||
#### Scenario: 主配置模板
|
||
- **GIVEN** 系统需要生成Nginx主配置
|
||
- **WHEN** 初始化或配置变更
|
||
- **THEN** 使用预定义模板生成 `auto-deploy.conf`
|
||
- **AND** 模板支持变量替换(如端口范围、项目列表)
|
||
|
||
#### Scenario: 项目location模板
|
||
- **GIVEN** 需要为项目生成location配置
|
||
- **WHEN** 创建或更新项目配置
|
||
- **THEN** 使用location模板生成配置片段
|
||
- **AND** 支持SPA路由回退处理
|
||
|
||
### Requirement: 配置热重载
|
||
系统 SHALL 在配置变更后自动重载Nginx。
|
||
|
||
#### Scenario: 配置变更后重载
|
||
- **WHEN** Nginx配置文件被修改
|
||
- **THEN** 系统执行 `nginx -s reload` 命令
|
||
- **AND** 检查重载结果
|
||
- **AND** 失败时回滚配置并记录错误日志
|
||
|
||
### Requirement: 环境配置扩展
|
||
系统 SHALL 扩展环境配置以支持Nginx相关设置。
|
||
|
||
#### Scenario: 新增环境变量
|
||
- **GIVEN** 用户配置 `.env` 文件
|
||
- **WHEN** 系统读取配置
|
||
- **THEN** 支持以下新增配置项:
|
||
- `USE_NGINX` - 是否使用Nginx(true/false/auto)
|
||
- `NGINX_CONFIG_DIR` - Nginx配置目录路径
|
||
- `NGINX_TEMPLATE_PATH` - 配置模板路径
|
||
- `NGINX_RELOAD_CMD` - Nginx重载命令
|
||
|
||
## MODIFIED Requirements
|
||
|
||
### Requirement: 项目URL生成
|
||
**原需求**: 项目URL格式为 `http://{domain}:{port}/`
|
||
**修改为**: 项目URL格式为 `{BASE_URL}/project/{projectId}/`
|
||
|
||
### Requirement: 端口管理
|
||
**原需求**: 项目使用外部可访问端口(9000-9100)
|
||
**修改为**: 项目使用内部端口(127.0.0.1:9000-9100),外部通过Nginx代理访问
|
||
|
||
## Technical Design
|
||
|
||
### 架构设计
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ Nginx (80/443) │
|
||
│ │
|
||
│ location /project/xxx/ { │
|
||
│ proxy_pass http://127.0.0.1:9000│
|
||
│ } │
|
||
└──────────────┬──────────────────────┘
|
||
│
|
||
┌────────────────────┼────────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||
│ 项目1 │ │ 项目2 │ │ 项目N │
|
||
│ :9000 │ │ :9001 │ │ :90xx │
|
||
│(内部端口) │ │(内部端口) │ │(内部端口) │
|
||
└──────────┘ └──────────┘ └──────────┘
|
||
```
|
||
|
||
### 文件结构
|
||
|
||
```
|
||
server/
|
||
├── services/
|
||
│ ├── nginxManager.js # 新增:Nginx配置管理
|
||
│ ├── processManager.js # 修改:端口绑定127.0.0.1
|
||
│ └── projectService.js # 修改:URL生成逻辑
|
||
├── templates/
|
||
│ └── nginx/
|
||
│ ├── main.conf.tpl # 主配置模板
|
||
│ └── location.conf.tpl # location配置模板
|
||
└── config/
|
||
└── index.js # 修改:新增Nginx配置项
|
||
|
||
nginx/
|
||
└── sites-enabled/
|
||
└── auto-deploy.conf # 生成的Nginx配置
|
||
```
|
||
|
||
### Nginx配置模板示例
|
||
|
||
**主配置模板 (main.conf.tpl)**:
|
||
```nginx
|
||
# Auto-generated by auto-deploy-demo
|
||
# Do not edit manually
|
||
|
||
upstream projects {
|
||
# 项目upstream配置将由系统自动生成
|
||
}
|
||
|
||
server {
|
||
listen {{PORT}};
|
||
server_name {{SERVER_NAME}};
|
||
|
||
# 管理后台
|
||
location / {
|
||
proxy_pass http://127.0.0.1:{{MANAGER_PORT}};
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
}
|
||
|
||
# API接口
|
||
location /api/ {
|
||
proxy_pass http://127.0.0.1:{{MANAGER_PORT}}/api/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
}
|
||
|
||
# 项目路由 - 由系统动态生成
|
||
{{PROJECT_LOCATIONS}}
|
||
}
|
||
```
|
||
|
||
**Location配置模板 (location.conf.tpl)**:
|
||
```nginx
|
||
# Project: {{PROJECT_NAME}} ({{PROJECT_ID}})
|
||
location /project/{{PROJECT_ID}}/ {
|
||
proxy_pass http://127.0.0.1:{{PROJECT_PORT}}/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
||
# SPA路由支持
|
||
try_files $uri $uri/ /project/{{PROJECT_ID}}/index.html;
|
||
}
|
||
```
|
||
|
||
### 核心流程
|
||
|
||
**项目启动流程**:
|
||
```
|
||
1. 查找可用内部端口
|
||
2. 启动项目服务(绑定127.0.0.1)
|
||
3. 生成/更新Nginx location配置
|
||
4. 重载Nginx
|
||
5. 返回项目URL: {BASE_URL}/project/{id}/
|
||
```
|
||
|
||
**项目停止流程**:
|
||
```
|
||
1. 停止项目进程
|
||
2. 更新Nginx配置(移除upstream或标记为down)
|
||
3. 重载Nginx
|
||
```
|
||
|
||
**项目删除流程**:
|
||
```
|
||
1. 停止项目(如运行中)
|
||
2. 删除项目文件
|
||
3. 移除Nginx location配置
|
||
4. 重载Nginx
|
||
```
|
||
|
||
### 本地开发模式
|
||
|
||
当 `USE_NGINX=auto` 时:
|
||
1. 检测系统是否安装Nginx
|
||
2. 检测Nginx配置目录是否可写
|
||
3. 若检测失败,回退到多端口模式
|
||
4. 在控制台输出当前模式信息
|
||
|
||
### 安全考虑
|
||
|
||
1. Nginx配置文件权限控制
|
||
2. 配置变更前备份
|
||
3. 配置验证(`nginx -t`)后再重载
|
||
4. 重载失败时回滚
|