Files
sbnews/docs/superpowers/specs/2026-08-02-production-docker-compose-design.md
T

8.1 KiB
Raw Blame History

Sport Era 生产 Docker Compose 设计

1. 目标

在生产服务器 /www/wwwroot/sbnews 中固定使用 dev.1.0.0 分支,通过一份统一的生产 Compose 编排运行 Sport Era 的 API、定时任务、爬虫、AI 知识库 Worker、管理后台和 uni-app H5。

生产环境继续使用宿主机 MySQL、Redis 和宝塔 Nginx。Compose 不管理数据库数据,也不占用宿主机的 80、443 端口。

2. 域名与入口

宝塔 Nginx 负责域名、HTTPS 证书和公网入口,并反向代理到仅在宿主机回环地址监听的容器服务:

域名 服务 反向代理目标
api.sbnews.net ThinkPHP API http://127.0.0.1:8000
keislwo.sbnews.net Admin SPA http://127.0.0.1:5176
web.sbnews.net uni-app H5 SPA http://127.0.0.1:5177

容器不直接处理公网 TLS,也不直接暴露 80、443、9000 等内部服务端口。

3. Compose 服务

新增 docker/docker-compose.prod.ymlCompose 项目名为 sport-era-prod

3.1 Server

  • 使用项目 PHP 8.0 FPM 镜像及 OPcache。
  • 挂载 /www/wwwroot/sbnews/server/likeadmin_php/server
  • 挂载私有 PHP 生产环境文件为 /likeadmin_php/server/.env
  • 使用 host 网络访问宿主机 MySQL 和 Redis。
  • PHP-FPM 仅监听 127.0.0.1:9000
  • 使用 restart: unless-stopped 和有限大小的 Docker 日志。

3.2 API Nginx

  • 使用 host 网络,通过 127.0.0.1:9000 访问 PHP-FPM。
  • 仅监听 127.0.0.1:8000
  • 根目录为 /likeadmin_php/server/public
  • 支持 ThinkPHP 路由重写、上传大小限制、静态资源缓存和代理来源信息。
  • 挂载生产 Nginx 日志目录。

3.3 Scheduler

  • 与 Server 使用同一 PHP 镜像、源码和私有环境文件。
  • 使用 host 网络。
  • 独立循环执行 php think crontab,间隔 60 秒。
  • 不承载 HTTP 请求。

3.4 Crawler

  • 复用 docker/crawler/Dockerfile 构建的镜像。
  • 使用 host 网络连接宿主机 MySQL、Redis。
  • 复用现有 crawler_tasks.yaml 生成容器 cron。
  • 持久化 docker/crawler/logsdocker/crawler/data

3.5 KB Worker

  • 与 Crawler 复用同一镜像。
  • 使用 host 网络连接 MySQL、Redis。
  • 持续消费 Redis Stream ai:kb:sync:stream
  • 对文章、帖子、彩票和比赛内容生成知识库文档、切片及 Embedding。
  • 保留现有批量大小、阻塞时间和重试参数。

3.6 Admin

  • 使用 Node 20 多阶段构建。
  • 构建阶段安装锁定依赖并生成 Vite 生产资源。
  • VITE_APP_BASE_URL 固定传入 https://api.sbnews.net
  • 运行阶段只保留静态 Nginx 和构建产物。
  • Nginx 仅监听 127.0.0.1:5176,并配置 SPA 路由回退。

3.7 uni-app H5

  • 使用 Node 20 多阶段构建。
  • 构建阶段执行 H5 生产构建。
  • VITE_APP_BASE_URL 固定传入 https://api.sbnews.net
  • 修改用户端配置,使生产 API 地址来自构建环境变量,不继续固定指向测试域名。
  • 运行阶段只保留静态 Nginx 和 H5 构建产物。
  • Nginx 仅监听 127.0.0.1:5177,并配置 SPA 路由回退。

PC 前台不包含在本次生产 Compose 范围内。

4. 网络设计

所有需要访问宿主机 MySQL、Redis 或回环端口的服务采用 host 网络:

  • MySQL127.0.0.1:3300
  • Redis127.0.0.1:6377,数据库编号 2
  • PHP-FPM127.0.0.1:9000
  • API Nginx127.0.0.1:8000
  • Admin Nginx127.0.0.1:5176
  • H5 Nginx127.0.0.1:5177

host 网络避免修改宿主机数据库监听地址和账号授权范围。各 HTTP/FastCGI 端口必须显式绑定回环地址,防止绕过宝塔直接访问。

5. 配置与密钥

生产环境使用两份互不混用的私有配置:

5.1 PHP 配置

文件:docker/.env.server.production

  • 使用 ThinkPHP INI 风格配置。
  • 包含数据库、Redis 以及 Server 运行所需的其他私有参数。
  • 只存在于生产服务器,权限设置为 600
  • 挂载到 Server 和 Scheduler 的项目 .env

5.2 Crawler 配置

文件:docker/.env.crawler.production

  • 使用 dotenv 格式。
  • 包含 DQD_DB_*DQD_REDIS_*、Embedding 及爬虫所需私有参数。
  • 由 Crawler 与 KB Worker 共用。
  • 只存在于生产服务器,权限设置为 600

Git 只提交对应的 .example 文件,所有密码使用占位符。.gitignore 必须忽略真实生产配置。

server/config/cache.php 中现存的非空 Redis 默认密码需要清空;各环境必须通过私有 .env 显式提供密码。已经公开或进入源码历史的生产密码应在部署完成后轮换。

6. 持久化与日志

数据 宿主机位置
Server 源码、上传和运行目录 /www/wwwroot/sbnews/server
Crawler 日志 /www/wwwroot/sbnews/docker/crawler/logs
Crawler 锁与运行数据 /www/wwwroot/sbnews/docker/crawler/data
API Nginx 日志 /www/wwwroot/sbnews/docker/log/nginx/prod-logs
MySQL 数据 由宿主机/宝塔管理
Redis 数据 由宿主机/宝塔管理

所有 Compose 服务使用有限大小、有限文件数量的 Docker JSON 日志配置,防止日志无限增长。

7. 发布流程

生产目录固定跟踪 dev.1.0.0

cd /www/wwwroot/sbnews
git switch dev.1.0.0
git pull --ff-only origin dev.1.0.0
sudo docker compose -f docker/docker-compose.prod.yml config -q
sudo docker compose -f docker/docker-compose.prod.yml up -d --build

Admin 和 H5 每次部署都从当前提交重新构建。Server 继续挂载当前生产目录源码,更新代码后由新容器或现有挂载立即读取;执行统一 up -d --build 保证运行镜像和配置同步。

Compose 不自动执行数据库迁移、SQL 导入或破坏性数据操作。

8. 健康检查与验收

Compose 为 API、Admin 和 H5 配置健康检查。部署后至少执行:

sudo docker compose -f docker/docker-compose.prod.yml ps
curl -f http://127.0.0.1:8000/api/index/config
curl -I http://127.0.0.1:5176/
curl -I http://127.0.0.1:5177/

再通过公网域名检查宝塔反向代理和 HTTPS:

curl -I https://api.sbnews.net/api/index/config
curl -I https://keislwo.sbnews.net/
curl -I https://web.sbnews.net/

同时检查:

  • Server、Scheduler、Crawler、KB Worker 均持续运行。
  • Scheduler 能产生正常定时任务日志。
  • Crawler 的容器 cron 已正确生成。
  • KB Worker 已连接 Redis Stream,且没有持续重试错误。
  • Admin/H5 刷新子路由不会返回 404。
  • Git 跟踪文件中不存在真实数据库、Redis 或 AI 密钥。

9. 回滚

回滚前必须确认生产工作区没有人工修改:

git status --short

切换到已知正常提交并重新构建:

git switch --detach <正常提交ID>
sudo docker compose -f docker/docker-compose.prod.yml up -d --build

恢复跟踪生产分支:

git switch dev.1.0.0

构建失败时不主动删除旧容器或旧镜像,避免构建失败直接中断当前线上服务。

10. 实施文件范围

新增文件:

  • docker/docker-compose.prod.yml
  • docker/Dockerfile.admin
  • docker/Dockerfile.uniapp-h5
  • docker/config/nginx/conf.d/sport-era.prod-api.conf
  • docker/config/nginx/static/admin.conf
  • docker/config/nginx/static/uniapp-h5.conf
  • docker/config/php/conf.d/zz-opcache.prod.ini
  • docker/config/php/php-fpm.prod.conf
  • docker/.env.server.production.example
  • docker/.env.crawler.production.example
  • admin/.dockerignore
  • uniapp/.dockerignore
  • docs/生产环境Docker部署说明.md

修改文件:

  • .gitignore
  • uniapp/src/config/index.ts
  • server/config/cache.php
  • docs/业务进度管理.md

11. 实施验证边界

本地实施阶段执行静态 Compose 展开和配置检查,不自动执行完整 Admin/H5 构建,也不直接操作生产服务器。所有真实生产密钥由服务器管理员写入私有环境文件。

源码或运行配置修改完成后创建独立 Git 提交,不包含当前工作区中既有的社区页面或其他无关改动。由于会修改 server/config/cache.php,提交后按项目规范同步测试服;生产环境由服务器在 /www/wwwroot/sbnews 拉取并部署。