# 容器化部署 **本文档引用的文件** - [docker-compose.yml](file://docker-nginx/docker-compose.yml) - [bookapi.conf](file://docker-nginx/bookapi.conf) - [README.md](file://docker-nginx/README.md) - [DEPLOY.md](file://docs/DEPLOY.md) - [DEPLOY_PROD.md](file://DEPLOY_PROD.md) - [server/src/app.ts](file://server/src/app.ts) - [server/src/config/index.ts](file://server/src/config/index.ts) - [server/src/services/redis.service.ts](file://server/src/services/redis.service.ts) - [server/src/services/storage.service.ts](file://server/src/services/storage.service.ts) - [server/package.json](file://server/package.json) - [my-uniapp-vue3/package.json](file://my-uniapp-vue3/package.json) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向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配置说明(参考) ```mermaid graph TB subgraph "宿主机" Host["宿主机网络
端口映射: 80->80"] end subgraph "容器编排" Nginx["Nginx容器
nginx-bookapi"] Backend["后端容器
server"] end subgraph "存储" Uploads["上传目录
/data/ai/audio/server/uploads"] Videos["视频目录
/data/ai/audio/server/public/videos"] EnvFile[".env 环境变量
/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](file://docker-nginx/docker-compose.yml#L1-L12) - [bookapi.conf:1-15](file://docker-nginx/bookapi.conf#L1-L15) - [DEPLOY_PROD.md:266-294](file://DEPLOY_PROD.md#L266-L294) 章节来源 - [docker-compose.yml:1-12](file://docker-nginx/docker-compose.yml#L1-L12) - [bookapi.conf:1-15](file://docker-nginx/bookapi.conf#L1-L15) - [DEPLOY.md:1-251](file://docs/DEPLOY.md#L1-L251) - [DEPLOY_PROD.md:1-393](file://DEPLOY_PROD.md#L1-L393) ## 核心组件 - 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](file://docker-nginx/docker-compose.yml#L1-L12) - [bookapi.conf:1-15](file://docker-nginx/bookapi.conf#L1-L15) - [server/src/app.ts:92-94](file://server/src/app.ts#L92-L94) - [server/src/config/index.ts:69-117](file://server/src/config/index.ts#L69-L117) - [server/package.json:1-60](file://server/package.json#L1-L60) - [my-uniapp-vue3/package.json:1-65](file://my-uniapp-vue3/package.json#L1-L65) ## 架构总览 容器化部署采用“Nginx反向代理 + 后端服务”的双容器模式。Nginx负责域名解析与HTTP请求转发,后端处理业务逻辑与数据访问。 ```mermaid sequenceDiagram participant Client as "客户端浏览器" participant Nginx as "Nginx容器" participant Backend as "后端容器" Client->>Nginx : "HTTP 请求 (bookapi.rrbrr.com)" Nginx->>Nginx : "解析bookapi.conf
设置X-Forwarded-*头" Nginx->>Backend : "转发到 http : //host.docker.internal : 3000" Backend->>Backend : "路由匹配 /api/*" Backend-->>Nginx : "响应 (JSON/静态资源)" Nginx-->>Client : "返回响应" ``` 图表来源 - [bookapi.conf:5-13](file://docker-nginx/bookapi.conf#L5-L13) - [server/src/app.ts:92-130](file://server/src/app.ts#L92-L130) ## 详细组件分析 ### 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:容器非正常退出时自动重启 ```mermaid flowchart TD Start(["启动 docker-compose"]) --> Pull["拉取nginx镜像"] Pull --> Create["创建nginx-bookapi容器"] Create --> Mount["挂载bookapi.conf
只读"] Mount --> Expose["映射端口80:80"] Expose --> ExtraHosts["配置host.docker.internal"] ExtraHosts --> RestartPolicy["设置重启策略: unless-stopped"] RestartPolicy --> Ready(["Nginx就绪"]) ``` 图表来源 - [docker-compose.yml:1-12](file://docker-nginx/docker-compose.yml#L1-L12) 章节来源 - [docker-compose.yml:1-12](file://docker-nginx/docker-compose.yml#L1-L12) - [bookapi.conf:1-15](file://docker-nginx/bookapi.conf#L1-L15) - [README.md:1-41](file://docker-nginx/README.md#L1-L41) ### 后端服务(server) - 应用入口与路由 - 健康检查:GET /health - 路由注册:/api/*各类模块路由 - 环境变量与配置 - 端口:优先SERVER_PORT,其次PORT,默认3000 - JWT密钥与过期时间 - 阿里云百炼TTS相关配置 - 存储类型:oss或local - Redis连接参数 - 依赖服务 - MySQL:Prisma连接 - Redis:缓存与队列 - OSS:对象存储(可选) ```mermaid 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](file://server/src/config/index.ts#L69-L117) - [server/src/services/redis.service.ts:1-200](file://server/src/services/redis.service.ts#L1-L200) - [server/src/services/storage.service.ts:1-200](file://server/src/services/storage.service.ts#L1-L200) 章节来源 - [server/src/app.ts:92-130](file://server/src/app.ts#L92-L130) - [server/src/config/index.ts:69-117](file://server/src/config/index.ts#L69-L117) - [server/src/services/redis.service.ts:1-200](file://server/src/services/redis.service.ts#L1-L200) - [server/src/services/storage.service.ts:1-200](file://server/src/services/storage.service.ts#L1-L200) ### 容器间网络通信机制 - 默认网络 - Docker Compose默认创建一个桥接网络,容器可通过服务名相互访问 - 宿主机访问 - Nginx容器通过extra_hosts解析host.docker.internal - 在容器内使用http://host.docker.internal:3000访问宿主机上的后端服务 - 端口暴露 - 宿主机80端口映射至Nginx容器80端口 - 后端服务监听配置端口(默认3000),需确保未被占用 章节来源 - [docker-compose.yml:9-11](file://docker-nginx/docker-compose.yml#L9-L11) - [bookapi.conf:7-7](file://docker-nginx/bookapi.conf#L7-L7) ### 数据持久化方案 - 上传与视频文件 - 建议将后端uploads与public/videos目录以卷挂载方式持久化 - 生产环境示例路径:/data/ai/audio/server/uploads、/data/ai/audio/server/public/videos - 环境变量 - 建议将.env文件以卷挂载方式注入容器,便于动态调整配置 - 数据库 - MySQL与Redis建议独立容器或外部服务,通过环境变量连接 章节来源 - [DEPLOY_PROD.md:308-317](file://DEPLOY_PROD.md#L308-L317) - [server/src/config/index.ts:113-117](file://server/src/config/index.ts#L113-L117) ### 开发环境与生产环境差异 - 端口与域名 - 开发:Nginx监听80,代理到宿主机host.docker.internal:3000 - 生产:宝塔Nginx监听80/443,反向代理到127.0.0.1:3100 - 环境变量 - 生产示例包含:NODE_ENV、SERVER_PORT、JWT_SECRET、DASHSCOPE_*、DATABASE_URL、STORAGE_TYPE、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](file://docker-nginx/README.md#L1-L41) - [DEPLOY.md:140-197](file://docs/DEPLOY.md#L140-L197) - [DEPLOY_PROD.md:105-144](file://DEPLOY_PROD.md#L105-L144) - [DEPLOY_PROD.md:146-245](file://DEPLOY_PROD.md#L146-L245) ## 依赖关系分析 - 后端服务依赖 - 数据库:Prisma连接MySQL - 缓存:ioredis连接Redis - 存储:ossService或本地FS - Nginx依赖 - 反向代理到后端容器的host.docker.internal:3000 - 前端依赖 - 构建产物H5目录由Nginx提供静态文件服务 ```mermaid graph LR Nginx["Nginx容器"] --> Backend["后端容器"] Backend --> MySQL["MySQL服务"] Backend --> Redis["Redis服务"] Backend --> OSS["阿里云OSS"] Frontend["前端H5"] --> Nginx ``` 图表来源 - [server/src/app.ts:138-151](file://server/src/app.ts#L138-L151) - [server/src/services/redis.service.ts:7-38](file://server/src/services/redis.service.ts#L7-L38) - [server/src/services/storage.service.ts:43-63](file://server/src/services/storage.service.ts#L43-L63) - [DEPLOY_PROD.md:266-294](file://DEPLOY_PROD.md#L266-L294) 章节来源 - [server/src/app.ts:138-151](file://server/src/app.ts#L138-L151) - [server/src/services/redis.service.ts:1-200](file://server/src/services/redis.service.ts#L1-L200) - [server/src/services/storage.service.ts:1-200](file://server/src/services/storage.service.ts#L1-L200) - [DEPLOY_PROD.md:266-294](file://DEPLOY_PROD.md#L266-L294) ## 性能考虑 - Nginx静态资源缓存与压缩 - 生产Nginx配置中对JS/CSS/图片设置了较长缓存与immutable属性 - 后端性能监控 - 后端内置性能监控中间件与指标接口(/api/metrics) - 存储与缓存 - Redis缓存提升热点数据访问性能 - OSS适合大规模静态资源分发 - 并发与队列 - 后端使用队列处理长耗时任务(书籍生成等) 章节来源 - [server/src/app.ts:23-24](file://server/src/app.ts#L23-L24) - [server/src/app.ts:97-97](file://server/src/app.ts#L97-L97) - [server/src/services/redis.service.ts:1-200](file://server/src/services/redis.service.ts#L1-L200) - [DEPLOY_PROD.md:223-237](file://DEPLOY_PROD.md#L223-L237) ## 故障排查指南 - Nginx 502/504 - 检查后端服务是否启动且监听指定端口 - 核对Nginx配置与反代地址 - 容器无法访问宿主机 - 确认extra_hosts配置与host.docker.internal解析 - 若无法解析,改用宿主机局域网IP直连 - 后端服务无法启动 - 查看PM2日志或容器日志 - 检查环境变量与数据库连接 - 数据库连接失败 - 检查MySQL容器状态与密码 - 使用Prisma迁移命令进行数据库同步 章节来源 - [README.md:30-41](file://docker-nginx/README.md#L30-L41) - [DEPLOY.md:200-214](file://docs/DEPLOY.md#L200-L214) - [DEPLOY_PROD.md:348-375](file://DEPLOY_PROD.md#L348-L375) ## 结论 本容器化方案以Nginx作为统一入口,配合后端服务实现高可用与易维护的部署架构。通过合理的端口映射、卷挂载与环境变量管理,可在开发与生产环境中快速切换。建议在生产中结合宝塔面板或Kubernetes进行更精细的资源调度与监控。 ## 附录 ### 容器启动/停止/重启标准流程 - 启动 - 开发:进入docker-nginx目录,执行docker-compose up -d - 验证:curl http://bookapi.rrbrr.com/api/health - 停止 - docker-compose down - 重启 - docker-compose restart - 重载Nginx配置(开发) - docker-compose exec nginx nginx -s reload 章节来源 - [README.md:5-28](file://docker-nginx/README.md#L5-L28) ### 健康检查与自动重启 - 健康检查 - 后端提供/health接口,可用于外部探针或容器编排健康检查 - 自动重启 - Nginx容器设置restart: unless-stopped - 生产环境可结合PM2实现后端进程自动重启 章节来源 - [server/src/app.ts:92-94](file://server/src/app.ts#L92-L94) - [docker-compose.yml:11-11](file://docker-nginx/docker-compose.yml#L11-L11) - [DEPLOY.md:161-185](file://docs/DEPLOY.md#L161-L185)