auto-deploy-demo/.trae/specs/nginx-dynamic-routing/spec.md

256 lines
8.4 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.

# 动态路由与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` - 是否使用Nginxtrue/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. 重载失败时回滚