容器化部署
本文档引用的文件
- docker-compose.yml
- bookapi.conf
- README.md
- DEPLOY.md
- DEPLOY_PROD.md
- server/src/app.ts
- server/src/config/index.ts
- server/src/services/redis.service.ts
- server/src/services/storage.service.ts
- server/package.json
- my-uniapp-vue3/package.json
目录
- 简介
- 项目结构
- 核心组件
- 架构总览
- 详细组件分析
- 依赖关系分析
- 性能考虑
- 故障排查指南
- 结论
- 附录
简介
本文件面向AI有声书生成平台的容器化部署,聚焦于基于Docker Compose的Nginx反向代理与后端服务编排。内容涵盖:
- Docker Compose配置结构与服务定义
- Nginx反向代理的端口映射、卷挂载与请求转发策略
- 容器间网络通信与数据持久化方案
- 开发与生产环境的配置差异(环境变量、配置文件挂载、日志输出)
- 容器生命周期管理(启动/停止/重启)与健康检查、自动重启机制
项目结构
围绕容器化部署的关键文件与目录如下:
- docker-nginx:包含Nginx反向代理的Compose与配置
- server:后端Node.js应用(Koa)
- my-uniapp-vue3:前端UniApp构建产物(H5)
- docs/DEPLOY.md:传统部署与PM2管理说明(参考)
DEPLOY_PROD.md:生产环境部署与宝塔Nginx配置说明(参考)
graph TB
subgraph "宿主机"
Host["宿主机网络<br/>端口映射: 80->80"]
end
subgraph "容器编排"
Nginx["Nginx容器<br/>nginx-bookapi"]
Backend["后端容器<br/>server"]
end
subgraph "存储"
Uploads["上传目录<br/>/data/ai/audio/server/uploads"]
Videos["视频目录<br/>/data/ai/audio/server/public/videos"]
EnvFile[".env 环境变量<br/>/data/ai/audio/server/.env"]
end
Host --> |"80/tcp"| Nginx
Nginx --> |"http://host.docker.internal:3000"| Backend
Backend --> |"MySQL:3306"| Host
Backend --> |"Redis:6379"| Host
Backend -. 卷挂载 .-> Uploads
Backend -. 卷挂载 .-> Videos
Backend -. 卷挂载 .-> EnvFile
图表来源
- docker-compose.yml:1-12
- bookapi.conf:1-15
- DEPLOY_PROD.md:266-294
章节来源
- docker-compose.yml:1-12
- bookapi.conf:1-15
- DEPLOY.md:1-251
- DEPLOY_PROD.md:1-393
核心组件
- Nginx反向代理服务
- 使用官方Nginx镜像,容器名为nginx-bookapi
- 将宿主80端口映射至容器80端口
- 挂载bookapi.conf作为只读配置文件
- 通过extra_hosts允许容器访问宿主机host.docker.internal
- 重启策略unless-stopped,实现异常退出后的自动重启
- 后端服务(server)
- 基于Node.js/Koa,监听配置中的端口(默认3000)
- 提供/api/*路由与/health健康检查接口
- 通过环境变量控制端口、TTS模型、存储类型、Redis等
- 依赖MySQL与Redis,支持阿里云OSS或本地存储
- 前端(my-uniapp-vue3)
- 构建产物位于dist/,可由Nginx直接提供静态文件服务
- 生产环境Nginx配置中指向/data/ai/audio/frontend/build/h5
章节来源
- docker-compose.yml:1-12
- bookapi.conf:1-15
- server/src/app.ts:92-94
- server/src/config/index.ts:69-117
- server/package.json:1-60
- my-uniapp-vue3/package.json:1-65
架构总览
容器化部署采用“Nginx反向代理 + 后端服务”的双容器模式。Nginx负责域名解析与HTTP请求转发,后端处理业务逻辑与数据访问。
sequenceDiagram
participant Client as "客户端浏览器"
participant Nginx as "Nginx容器"
participant Backend as "后端容器"
Client->>Nginx : "HTTP 请求 (bookapi.rrbrr.com)"
Nginx->>Nginx : "解析bookapi.conf<br/>设置X-Forwarded-*头"
Nginx->>Backend : "转发到 http : //host.docker.internal : 3000"
Backend->>Backend : "路由匹配 /api/*"
Backend-->>Nginx : "响应 (JSON/静态资源)"
Nginx-->>Client : "返回响应"
图表来源
- bookapi.conf:5-13
- server/src/app.ts:92-130
详细组件分析
Nginx反向代理服务
- 服务名称与镜像
- 服务名:nginx
- 镜像:nginx:latest
- 容器名:nginx-bookapi
- 端口映射
- "80:80":将宿主机80端口映射到容器80端口
- 卷挂载
- ./bookapi.conf:/etc/nginx/conf.d/bookapi.conf:ro:挂载只读配置文件
- 网络与主机访问
- extra_hosts配置允许容器解析host.docker.internal
重启策略
unless-stopped:容器非正常退出时自动重启
flowchart TD
Start(["启动 docker-compose"]) --> Pull["拉取nginx镜像"]
Pull --> Create["创建nginx-bookapi容器"]
Create --> Mount["挂载bookapi.conf<br/>只读"]
Mount --> Expose["映射端口80:80"]
Expose --> ExtraHosts["配置host.docker.internal"]
ExtraHosts --> RestartPolicy["设置重启策略: unless-stopped"]
RestartPolicy --> Ready(["Nginx就绪"])
图表来源
章节来源
- docker-compose.yml:1-12
- bookapi.conf:1-15
- README.md:1-41
后端服务(server)
- 应用入口与路由
- 健康检查:GET /health
- 路由注册:/api/*各类模块路由
- 环境变量与配置
- 端口:优先SERVER_PORT,其次PORT,默认3000
- JWT密钥与过期时间
- 阿里云百炼TTS相关配置
- 存储类型:oss或local
- Redis连接参数
依赖服务
- MySQL:Prisma连接
- Redis:缓存与队列
OSS:对象存储(可选)
classDiagram
class Config {
+number port
+string nodeEnv
+object jwt
+object dashscope
+object models
+object upload
}
class RedisService {
+isAvailable() boolean
+get(key) Promise~string|null~
+set(key,value,ttl) Promise~boolean~
+getJSON(key) Promise~any~
+setJSON(key,value,ttl) Promise~boolean~
+del(key) Promise~boolean~
+delPattern(pattern) Promise~boolean~
+hset(key,field,value) Promise~boolean~
+hget(key,field) Promise~string|null~
+hgetall(key) Promise~object|null~
}
class StorageService {
+setStorageType(type)
+getStorageType() StorageType
+uploadAudio(localPath,audioId) Promise~string~
+uploadVideo(localPath,videoId) Promise~string~
+uploadCover(localPath,bookId) Promise~string~
+uploadFile(localPath,category,id) Promise~string~
+uploadBuffer(buffer,objectKey,content) Promise~string~
+deleteFile(url) Promise~void~
+deleteDirectory(prefix,id) Promise~void~
+downloadFile(url) Promise~Buffer~
+getSignedUrl(url,expires) Promise~string~
}
Config --> RedisService : "读取Redis配置"
Config --> StorageService : "读取存储类型"
图表来源
- server/src/config/index.ts:69-117
- server/src/services/redis.service.ts:1-200
- server/src/services/storage.service.ts:1-200
章节来源
- server/src/app.ts:92-130
- server/src/config/index.ts:69-117
- server/src/services/redis.service.ts:1-200
- server/src/services/storage.service.ts:1-200
容器间网络通信机制
- 默认网络
- Docker Compose默认创建一个桥接网络,容器可通过服务名相互访问
- 宿主机访问
- Nginx容器通过extra_hosts解析host.docker.internal
- 在容器内使用http://host.docker.internal:3000访问宿主机上的后端服务
- 端口暴露
- 宿主机80端口映射至Nginx容器80端口
- 后端服务监听配置端口(默认3000),需确保未被占用
章节来源
- docker-compose.yml:9-11
- bookapi.conf:7-7
数据持久化方案
- 上传与视频文件
- 建议将后端uploads与public/videos目录以卷挂载方式持久化
- 生产环境示例路径:/data/ai/audio/server/uploads、/data/ai/audio/server/public/videos
- 环境变量
- 建议将.env文件以卷挂载方式注入容器,便于动态调整配置
- 数据库
- MySQL与Redis建议独立容器或外部服务,通过环境变量连接
章节来源
- DEPLOY_PROD.md:308-317
- server/src/config/index.ts:113-117
开发环境与生产环境差异
- 端口与域名
- 开发:Nginx监听80,代理到宿主机host.docker.internal:3000
- 生产:宝塔Nginx监听80/443,反向代理到127.0.0.1:3100
- 环境变量
- 生产示例包含:NODE_ENV、SERVER_PORT、JWTSECRET、DASHSCOPE*、DATABASE_URL、STORAGETYPE、REDIS*、OSS_*、MINIMAX_API_KEY
- 配置文件挂载
- 开发:Nginx配置文件通过卷挂载
- 生产:宝塔面板管理Nginx配置,路径位于/www/server/panel/vhost/nginx/
- 日志输出
- 后端使用Winston记录日志;生产环境建议结合宝塔日志或容器日志收集
- Nginx访问/错误日志:/var/log/nginx/access.log、/var/log/nginx/error.log
章节来源
- README.md:1-41
- DEPLOY.md:140-197
- DEPLOY_PROD.md:105-144
- DEPLOY_PROD.md:146-245
依赖关系分析
- 后端服务依赖
- 数据库:Prisma连接MySQL
- 缓存:ioredis连接Redis
- 存储:ossService或本地FS
- Nginx依赖
- 反向代理到后端容器的host.docker.internal:3000
前端依赖
图表来源
- server/src/app.ts:138-151
- server/src/services/redis.service.ts:7-38
- server/src/services/storage.service.ts:43-63
- DEPLOY_PROD.md:266-294
章节来源
- server/src/app.ts:138-151
- server/src/services/redis.service.ts:1-200
- server/src/services/storage.service.ts:1-200
- DEPLOY_PROD.md:266-294
性能考虑
- Nginx静态资源缓存与压缩
- 生产Nginx配置中对JS/CSS/图片设置了较长缓存与immutable属性
- 后端性能监控
- 后端内置性能监控中间件与指标接口(/api/metrics)
- 存储与缓存
- Redis缓存提升热点数据访问性能
- OSS适合大规模静态资源分发
- 并发与队列
章节来源
- server/src/app.ts:23-24
- server/src/app.ts:97-97
- server/src/services/redis.service.ts:1-200
- DEPLOY_PROD.md:223-237
故障排查指南
- Nginx 502/504
- 检查后端服务是否启动且监听指定端口
- 核对Nginx配置与反代地址
- 容器无法访问宿主机
- 确认extra_hosts配置与host.docker.internal解析
- 若无法解析,改用宿主机局域网IP直连
- 后端服务无法启动
- 查看PM2日志或容器日志
- 检查环境变量与数据库连接
- 数据库连接失败
- 检查MySQL容器状态与密码
- 使用Prisma迁移命令进行数据库同步
章节来源
- README.md:30-41
- DEPLOY.md:200-214
- DEPLOY_PROD.md:348-375
结论
本容器化方案以Nginx作为统一入口,配合后端服务实现高可用与易维护的部署架构。通过合理的端口映射、卷挂载与环境变量管理,可在开发与生产环境中快速切换。建议在生产中结合宝塔面板或Kubernetes进行更精细的资源调度与监控。
附录
容器启动/停止/重启标准流程
- 启动
- 停止
- 重启
- 重载Nginx配置(开发)
- docker-compose exec nginx nginx -s reload
章节来源
健康检查与自动重启
- 健康检查
- 后端提供/health接口,可用于外部探针或容器编排健康检查
- 自动重启
- Nginx容器设置restart: unless-stopped
- 生产环境可结合PM2实现后端进程自动重启
章节来源
- server/src/app.ts:92-94
- docker-compose.yml:11-11
- DEPLOY.md:161-185