84 lines
5.0 KiB
Markdown
84 lines
5.0 KiB
Markdown
---
|
||
kind: configuration_system
|
||
name: 前后端配置系统与环境变量管理
|
||
category: configuration_system
|
||
scope:
|
||
- '**'
|
||
source_files:
|
||
- backend/src/app.js
|
||
- backend/src/config/loadEnv.js
|
||
- backend/src/config/env.js
|
||
- backend/src/config/database.js
|
||
- backend/src/config/redis.js
|
||
- backend/src/config/logger.js
|
||
- docker-compose.yml
|
||
- frontend/.env
|
||
- frontend/.env.prod
|
||
- frontend/.env.test
|
||
- frontend/vite.config.ts
|
||
---
|
||
|
||
## 1. 系统概览
|
||
|
||
本项目采用**前后端分离 + Docker Compose 编排**的架构,配置系统围绕“环境变量优先、文件兜底”的原则组织:
|
||
|
||
- **后端(Node.js/Express)**:通过 `dotenv` 从仓库根目录 `.env` 加载,Docker 部署时由 `docker-compose.yml` 的 `env_file` 注入,不覆盖已有环境变量。
|
||
- **前端(Vite)**:使用 Vite 内置的 `loadEnv`,按构建模式(development / test / production)分别读取 `.env`、`.env.test`、`.env.prod`,所有 `VITE_` 前缀变量在构建期注入到 `import.meta.env`。
|
||
- **容器编排**:`docker-compose.yml` 通过 `env_file` 和 `environment` 为后端注入运行时配置,并通过端口映射与 Nginx 静态资源卷完成服务暴露。
|
||
|
||
## 2. 关键文件与包
|
||
|
||
| 层级 | 文件 | 作用 |
|
||
|------|------|------|
|
||
| 后端入口 | `backend/src/app.js` | 首行 `require('./config/loadEnv')` 触发 .env 加载;集中挂载中间件、路由、启动监听 |
|
||
| 环境判断 | `backend/src/config/env.js` | 基于 `APP_ENV` 导出 `isDevelopment` / `isProduction` 布尔值 |
|
||
| 环境变量加载 | `backend/src/config/loadEnv.js` | 仅当根目录存在 `.env` 时才调用 `dotenv.config`,避免覆盖容器注入的环境变量 |
|
||
| 数据库配置 | `backend/src/config/database.js` | 从 `DATABASE_*` 环境变量构造 Sequelize 实例,开发模式开启 SQL 日志 |
|
||
| Redis 缓存 | `backend/src/config/redis.js` | 懒初始化 ioredis 客户端,支持密码与多 DB 选择 |
|
||
| 日志配置 | `backend/src/config/logger.js` | winston 双传输(Console + File),固定输出到 `backend/logs/app.log` |
|
||
| 容器编排 | `docker-compose.yml` | 定义 backend/frontend 两个服务,通过 `env_file: .env` 注入后端配置,固定 `PORT=8000` |
|
||
| 前端基础配置 | `frontend/.env` | 应用标题、路由模式、代理开关等通用 Vite 变量 |
|
||
| 前端生产配置 | `frontend/.env.prod` | 指定 `VITE_SERVICE_BASE_URL=/api`(同域 Nginx 反代) |
|
||
| 前端测试配置 | `frontend/.env.test` | 指向本地后端 `http://localhost:8083/api` |
|
||
| Vite 构建脚本 | `frontend/vite.config.ts` | 通过 `loadEnv(mode, cwd)` 读取对应 `.env.*`,并注入 `base`、`proxy`、`define` 等 |
|
||
|
||
## 3. 架构与设计约定
|
||
|
||
### 3.1 后端配置加载顺序
|
||
|
||
```
|
||
进程启动 → app.js → require('./config/loadEnv')
|
||
→ dotenv.config({ path: root/.env }) // 仅当文件存在
|
||
→ 各模块直接 process.env.XXX 取值
|
||
```
|
||
|
||
- **优先级**:容器注入环境变量 > `.env` 文件默认值(`process.env.DATABASE_PASSWORD || 'root123'`)。
|
||
- **环境区分**:`APP_ENV` 决定 `isDevelopment` / `isProduction`,用于控制 Sequelize SQL 日志开关等。
|
||
|
||
### 3.2 前端配置加载顺序
|
||
|
||
```
|
||
vite serve/build → loadEnv(mode, cwd)
|
||
→ development: 读取 .env + .env.development
|
||
→ test: 读取 .env + .env.test
|
||
→ production: 读取 .env + .env.prod
|
||
→ 仅 VITE_* 前缀变量注入到 import.meta.env
|
||
```
|
||
|
||
- 生产构建产物不包含源码,因此 `VITE_SERVICE_BASE_URL=/api` 通过 Nginx 反向代理到后端 `/api`,实现同源部署。
|
||
- 开发/测试环境通过 `VITE_HTTP_PROXY=Y` 配合 `createViteProxy` 将请求转发到 `http://localhost:8083`。
|
||
|
||
### 3.3 容器化配置
|
||
|
||
- 后端容器内固定 `PORT=8000`,宿主机映射 `8083:8000`,与 Nginx `proxy_pass http://backend:8000` 一致。
|
||
- `extra_hosts: host.docker.internal:host-gateway` 允许容器访问宿主机 MySQL/Redis。
|
||
- 前端容器只挂载静态资源与 nginx.conf,无运行时配置。
|
||
|
||
## 4. 开发者应遵循的规则
|
||
|
||
1. **新增后端环境变量**:统一以 `DATABASE_*`、`REDIS_*`、`PORT`、`APP_ENV` 等大写命名,在 `backend/src/config/*.js` 中提供默认值,并在 `docker-compose.yml` 的 `env_file` 或 `environment` 中声明。
|
||
2. **不要修改 `loadEnv.js` 的加载逻辑**:它刻意只在本地存在 `.env` 时才加载,避免覆盖 Docker 注入的环境变量。
|
||
3. **新增前端环境变量**:必须以 `VITE_` 开头,放在对应环境的 `.env.*` 文件中;若需跨环境共享,放入根 `.env`。
|
||
4. **生产部署**:确保 `frontend/.env.prod` 的 `VITE_SERVICE_BASE_URL` 与 Nginx 的反代路径一致(当前为 `/api`)。
|
||
5. **敏感信息**:数据库密码、Redis 密码等不要提交到版本库,使用 `docker-compose.yml` 的 `env_file` 或宿主机的环境变量注入。
|
||
6. **日志位置**:后端日志固定写入 `backend/logs/app.log`,容器内可通过 volume 持久化到宿主机 `/data/projects/source`。 |