Standardize SurClaw ports away from defaults

- Change the API default listen port from 3000 to 3100 and include the Docker frontend origin in default CORS.

- Point Vite's default API proxy, Docker API container port, and Nginx upstream to 3100.

- Keep Docker host ports on 4002 for web, 3002 for API, and 5433 for PostgreSQL.

- Update environment examples and documentation to remove stale localhost:3000 guidance.
This commit is contained in:
2026-05-02 02:17:07 +08:00
parent 750cf4129d
commit 7c6449b7bd
11 changed files with 25 additions and 24 deletions

View File

@@ -1,9 +1,9 @@
# Backend API development defaults. # Backend API development defaults.
API_PORT=3000 API_PORT=3100
CORS_ORIGIN="http://localhost:3001" CORS_ORIGIN="http://localhost:3001,http://localhost:4002"
DATABASE_URL="postgresql://surclaw:surclaw_dev_password@localhost:5433/surclaw?schema=public" DATABASE_URL="postgresql://surclaw:surclaw_dev_password@localhost:5433/surclaw?schema=public"
SESSION_SECRET="change-me-in-production" SESSION_SECRET="change-me-in-production"
SESSION_COOKIE_SECURE="false" SESSION_COOKIE_SECURE="false"
FILE_STORAGE_DIR="./uploads" FILE_STORAGE_DIR="./uploads"
VITE_API_PROXY_TARGET="http://localhost:3000" VITE_API_PROXY_TARGET="http://localhost:3100"
VITE_ENABLE_LOCAL_FALLBACK="true" VITE_ENABLE_LOCAL_FALLBACK="true"

View File

@@ -24,7 +24,7 @@
```bash ```bash
npm install npm install
npm run dev # Vite dev server, 0.0.0.0:3001 npm run dev # Vite dev server, 0.0.0.0:3001
npm run server:dev # build and start NestJS API, 0.0.0.0:3000 npm run server:dev # build and start NestJS API, 0.0.0.0:3100
npm run server:build # tsc -p server/tsconfig.json npm run server:build # tsc -p server/tsconfig.json
npm run lint # tsc --noEmit npm run lint # tsc --noEmit
npm run test # vitest run npm run test # vitest run
@@ -287,7 +287,7 @@ npm run test:e2e
统一前端 API 请求封装: 统一前端 API 请求封装:
- 默认请求相对路径 `/api/...` - 默认请求相对路径 `/api/...`
- Vite 开发模式通过 `VITE_API_PROXY_TARGET` 代理 API默认 `http://localhost:3000` - Vite 开发模式通过 `VITE_API_PROXY_TARGET` 代理 API默认 `http://localhost:3100`
- 请求带 `credentials: 'include'`,用于后端 HttpOnly Session Cookie。 - 请求带 `credentials: 'include'`,用于后端 HttpOnly Session Cookie。
- 解包后端 `{ data }` 响应,错误时抛出 `ApiError` - 解包后端 `{ data }` 响应,错误时抛出 `ApiError`

View File

@@ -17,5 +17,5 @@ COPY --from=builder /app/server/dist ./server/dist
COPY --from=builder /app/server/prisma ./server/prisma COPY --from=builder /app/server/prisma ./server/prisma
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
EXPOSE 3000 EXPOSE 3100
CMD ["node", "server/dist/main.js"] CMD ["node", "server/dist/main.js"]

View File

@@ -51,7 +51,7 @@ http://localhost:3001
``` ```
`npm run dev` 实际使用 `vite --port=3001 --host=0.0.0.0`,局域网内也可以通过机器 IP 访问。 `npm run dev` 实际使用 `vite --port=3001 --host=0.0.0.0`,局域网内也可以通过机器 IP 访问。
开发模式下 Vite 会把 `/api` 代理到 `VITE_API_PROXY_TARGET`,默认是 `http://localhost:3000`。如果只启动 Docker Compose 中的 API再用本机 Vite 前端调试,可把该变量改成 `http://localhost:3002` 开发模式下 Vite 会把 `/api` 代理到 `VITE_API_PROXY_TARGET`,默认是 `http://localhost:3100`。如果只启动 Docker Compose 中的 API再用本机 Vite 前端调试,可把该变量改成 `http://localhost:3002`
后端 API 开发服务默认监听: 后端 API 开发服务默认监听:
@@ -62,7 +62,7 @@ npm run server:dev
``` ```
```text ```text
http://localhost:3000/api/health http://localhost:3100/api/health
``` ```
如果需要真实数据库,先启动 PostgreSQL 并配置 `DATABASE_URL`,再执行: 如果需要真实数据库,先启动 PostgreSQL 并配置 `DATABASE_URL`,再执行:
@@ -87,7 +87,7 @@ npm run prisma:seed
```bash ```bash
npm run dev # 启动开发服务器,端口 3001 npm run dev # 启动开发服务器,端口 3001
npm run server:dev # 编译并启动 NestJS API默认端口 3000 npm run server:dev # 编译并启动 NestJS API默认端口 3100
npm run server:build # 构建后端 TypeScript npm run server:build # 构建后端 TypeScript
npm run lint # TypeScript 类型检查 npm run lint # TypeScript 类型检查
npm run test # Vitest 测试 npm run test # Vitest 测试
@@ -118,13 +118,13 @@ cp .env.example .env.local
当前环境变量: 当前环境变量:
- `API_PORT`NestJS API 监听端口,本地直接运行默认 `3000`Docker Compose 暴露到宿主机的默认端口是 `3002` - `API_PORT`NestJS API 监听端口,本地直接运行默认 `3100`Docker Compose 暴露到宿主机的默认端口是 `3002`
- `CORS_ORIGIN`:允许携带 Cookie 访问 API 的前端来源。 - `CORS_ORIGIN`:允许携带 Cookie 访问 API 的前端来源。
- `DATABASE_URL`PostgreSQL 连接串。Docker Compose 暴露到宿主机的默认端口是 `5433`,容器内部仍使用 `db:5432` - `DATABASE_URL`PostgreSQL 连接串。Docker Compose 暴露到宿主机的默认端口是 `5433`,容器内部仍使用 `db:5432`
- `SESSION_SECRET`:后端 Session Cookie 签名密钥,生产环境必须替换。 - `SESSION_SECRET`:后端 Session Cookie 签名密钥,生产环境必须替换。
- `SESSION_COOKIE_SECURE`:是否只通过 HTTPS 发送 Session Cookie。本地 HTTP/Compose 默认 `false` - `SESSION_COOKIE_SECURE`:是否只通过 HTTPS 发送 Session Cookie。本地 HTTP/Compose 默认 `false`
- `FILE_STORAGE_DIR`后端文件存储目录。Docker Compose 默认挂载到 `/app/uploads` - `FILE_STORAGE_DIR`后端文件存储目录。Docker Compose 默认挂载到 `/app/uploads`
- `VITE_API_PROXY_TARGET`Vite 开发服务器的 `/api` 代理目标。直接运行 `npm run server:dev` 时用 `http://localhost:3000`;连接 Docker Compose API 时用 `http://localhost:3002` - `VITE_API_PROXY_TARGET`Vite 开发服务器的 `/api` 代理目标。直接运行 `npm run server:dev` 时用 `http://localhost:3100`;连接 Docker Compose API 时用 `http://localhost:3002`
- `VITE_ENABLE_LOCAL_FALLBACK`:是否允许生产构建继续使用浏览器本地兼容回退。开发模式默认启用,生产默认关闭。 - `VITE_ENABLE_LOCAL_FALLBACK`:是否允许生产构建继续使用浏览器本地兼容回退。开发模式默认启用,生产默认关闭。
注意:当前 AI/语音密钥由后端设置读取并在代理中使用,普通用户读取设置时不返回真实密钥。视频和关键帧文件已优先写入后端,报告内媒体引用通过 `ReportMedia` 关系表保存。 注意:当前 AI/语音密钥由后端设置读取并在代理中使用,普通用户读取设置时不返回真实密钥。视频和关键帧文件已优先写入后端,报告内媒体引用通过 `ReportMedia` 关系表保存。

View File

@@ -19,14 +19,14 @@ services:
container_name: tuwen_api container_name: tuwen_api
restart: unless-stopped restart: unless-stopped
environment: environment:
API_PORT: 3000 API_PORT: 3100
CORS_ORIGIN: http://localhost:4002,http://localhost:3001 CORS_ORIGIN: http://localhost:4002,http://localhost:3001
DATABASE_URL: postgresql://surclaw:surclaw_dev_password@db:5432/surclaw?schema=public DATABASE_URL: postgresql://surclaw:surclaw_dev_password@db:5432/surclaw?schema=public
SESSION_SECRET: change-me-in-production SESSION_SECRET: change-me-in-production
SESSION_COOKIE_SECURE: "false" SESSION_COOKIE_SECURE: "false"
FILE_STORAGE_DIR: /app/uploads FILE_STORAGE_DIR: /app/uploads
ports: ports:
- "3002:3000" - "3002:3100"
depends_on: depends_on:
- db - db
volumes: volumes:

View File

@@ -29,6 +29,6 @@
- 技术栈React 19、TypeScript、Vite 6、Tailwind CSS 4、React Router DOM 7、NestJS、Prisma、PostgreSQL。 - 技术栈React 19、TypeScript、Vite 6、Tailwind CSS 4、React Router DOM 7、NestJS、Prisma、PostgreSQL。
- 应用类型:前端 SPA + NestJS API。登录、报告、模板、用户管理、部门模板授权、系统设置和签名文件已接入后端其余主业务页面仍处于迁移期。 - 应用类型:前端 SPA + NestJS API。登录、报告、模板、用户管理、部门模板授权、系统设置和签名文件已接入后端其余主业务页面仍处于迁移期。
- 数据层:认证用户、报告、报告媒体关系、模板、字段库、模板图片资源、视频/关键帧文件、用户管理、部门模板授权、系统设置和签名文件来自 PostgreSQL/后端文件目录。 - 数据层:认证用户、报告、报告媒体关系、模板、字段库、模板图片资源、视频/关键帧文件、用户管理、部门模板授权、系统设置和签名文件来自 PostgreSQL/后端文件目录。
- 本地开发端口:前端 `3001`,后端 API `3000`Docker Compose 暴露 API 到宿主机 `3002` - 本地开发端口:前端 `3001`,后端 API `3100`Docker Compose 暴露 API 到宿主机 `3002`
- 默认账号:`admin / 123456``manager / 123456``0001 / 123456` - 默认账号:`admin / 123456``manager / 123456``0001 / 123456`
- 核心代码目录:`src/pages``src/components``src/utils``src/types.ts` - 核心代码目录:`src/pages``src/components``src/utils``src/types.ts`

View File

@@ -10,7 +10,7 @@ npm run dev
``` ```
开发服务监听 `0.0.0.0:3001` 开发服务监听 `0.0.0.0:3001`
开发模式下 Vite 会把 `/api` 代理到 `VITE_API_PROXY_TARGET`,默认 `http://localhost:3000` 开发模式下 Vite 会把 `/api` 代理到 `VITE_API_PROXY_TARGET`,默认 `http://localhost:3100`
后端: 后端:
@@ -20,10 +20,10 @@ npm run prisma:generate
npm run server:dev npm run server:dev
``` ```
本地直接运行 API 默认监听 `0.0.0.0:3000`,健康检查为: 本地直接运行 API 默认监听 `0.0.0.0:3100`,健康检查为:
```text ```text
http://localhost:3000/api/health http://localhost:3100/api/health
``` ```
如需连接真实 PostgreSQL 如需连接真实 PostgreSQL
@@ -56,13 +56,13 @@ AI 和语音密钥由后端 Settings API 保存并由代理使用,前端不再
后端新增变量: 后端新增变量:
- `API_PORT`API 监听端口。本地直接运行默认 `3000`Docker Compose 暴露到宿主机的默认端口是 `3002` - `API_PORT`API 监听端口。本地直接运行默认 `3100`Docker Compose 暴露到宿主机的默认端口是 `3002`
- `CORS_ORIGIN`:允许跨域携带 Cookie 的前端来源。 - `CORS_ORIGIN`:允许跨域携带 Cookie 的前端来源。
- `DATABASE_URL`PostgreSQL 连接串。Docker Compose 暴露到宿主机的默认端口是 `5433`,容器内部仍使用 `db:5432` - `DATABASE_URL`PostgreSQL 连接串。Docker Compose 暴露到宿主机的默认端口是 `5433`,容器内部仍使用 `db:5432`
- `SESSION_SECRET`Session Cookie 签名密钥。 - `SESSION_SECRET`Session Cookie 签名密钥。
- `SESSION_COOKIE_SECURE`:是否只通过 HTTPS 发送 Session Cookie。本地 HTTP/Compose 默认 `false`,生产 HTTPS 应设为 `true` - `SESSION_COOKIE_SECURE`:是否只通过 HTTPS 发送 Session Cookie。本地 HTTP/Compose 默认 `false`,生产 HTTPS 应设为 `true`
- `FILE_STORAGE_DIR`后端文件目录。Docker Compose 默认 `/app/uploads`,并挂载到 `uploads_data` volume。 - `FILE_STORAGE_DIR`后端文件目录。Docker Compose 默认 `/app/uploads`,并挂载到 `uploads_data` volume。
- `VITE_API_PROXY_TARGET`:前端开发服务器 `/api` 代理目标。直接运行后端用 `http://localhost:3000`;连接 Docker Compose API 用 `http://localhost:3002` - `VITE_API_PROXY_TARGET`:前端开发服务器 `/api` 代理目标。直接运行后端用 `http://localhost:3100`;连接 Docker Compose API 用 `http://localhost:3002`
- `VITE_ENABLE_LOCAL_FALLBACK`:生产构建是否允许本地兼容回退。开发模式默认启用,生产默认关闭。 - `VITE_ENABLE_LOCAL_FALLBACK`:生产构建是否允许本地兼容回退。开发模式默认启用,生产默认关闭。
## Docker 部署 ## Docker 部署

View File

@@ -54,7 +54,8 @@
| 日期 | 事项 | | 日期 | 事项 |
| --- | --- | | --- | --- |
| 2026-05-01 | 新增 `docs/` 文档结构,梳理当前需求、设计、模块和风险。 | | 2026-05-01 | 新增 `docs/` 文档结构,梳理当前需求、设计、模块和风险。 |
| 2026-05-01 | 本地开发端口`3000` 调整为 `3001`。 | | 2026-05-01 | 前端本地开发端口调整为 `3001`。 |
| 2026-05-02 | 统一端口配置:本地/API 容器监听 `3100`Docker API 暴露 `3002`Docker 前端暴露 `4002`,避免占用其他项目常用端口。 |
| 2026-05-01 | 新增功能盘点和测试文档,补充 Vitest 测试覆盖核心功能契约。 | | 2026-05-01 | 新增功能盘点和测试文档,补充 Vitest 测试覆盖核心功能契约。 |
| 2026-05-01 | 对齐前端权限 mock、报告修订版本和医生个人模板统一 `xfSpeechConfig` 字段。 | | 2026-05-01 | 对齐前端权限 mock、报告修订版本和医生个人模板统一 `xfSpeechConfig` 字段。 |
| 2026-05-01 | 新增 Playwright E2E 和 API 契约草案,锁定后端化前的关键前端行为。 | | 2026-05-01 | 新增 Playwright E2E 和 API 契约草案,锁定后端化前的关键前端行为。 |

View File

@@ -17,7 +17,7 @@ server {
} }
location /api/ { location /api/ {
proxy_pass http://api:3000/api/; proxy_pass http://api:3100/api/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; proxy_set_header Connection $connection_upgrade;

View File

@@ -12,12 +12,12 @@ import { SpeechService } from './speech/speech.service.js';
const bootstrap = async () => { const bootstrap = async () => {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
const port = Number(process.env.API_PORT ?? 3000); const port = Number(process.env.API_PORT ?? 3100);
app.setGlobalPrefix('api'); app.setGlobalPrefix('api');
app.useGlobalFilters(new ApiExceptionFilter()); app.useGlobalFilters(new ApiExceptionFilter());
app.enableCors({ app.enableCors({
origin: process.env.CORS_ORIGIN?.split(',') ?? ['http://localhost:3001'], origin: process.env.CORS_ORIGIN?.split(',') ?? ['http://localhost:3001', 'http://localhost:4002'],
credentials: true, credentials: true,
}); });
app.use(cookieParser()); app.use(cookieParser());

View File

@@ -6,7 +6,7 @@ import {defineConfig} from 'vitest/config';
export default defineConfig(({mode}) => { export default defineConfig(({mode}) => {
const env = loadEnv(mode, '.', ''); const env = loadEnv(mode, '.', '');
const apiProxyTarget = env.VITE_API_PROXY_TARGET || 'http://localhost:3000'; const apiProxyTarget = env.VITE_API_PROXY_TARGET || 'http://localhost:3100';
return { return {
plugins: [react(), tailwindcss()], plugins: [react(), tailwindcss()],
resolve: { resolve: {