From 0b9b2e8255fe349b659d6d965e9264beca4bc219 Mon Sep 17 00:00:00 2001 From: hajimi Date: Sun, 2 Aug 2026 02:47:40 +0800 Subject: [PATCH] docs: define production docker compose --- ...-08-02-production-docker-compose-design.md | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-02-production-docker-compose-design.md diff --git a/docs/superpowers/specs/2026-08-02-production-docker-compose-design.md b/docs/superpowers/specs/2026-08-02-production-docker-compose-design.md new file mode 100644 index 0000000..b7f4b2d --- /dev/null +++ b/docs/superpowers/specs/2026-08-02-production-docker-compose-design.md @@ -0,0 +1,231 @@ +# 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.yml`,Compose 项目名为 `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/logs` 与 `docker/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 网络: + +- MySQL:`127.0.0.1:3300` +- Redis:`127.0.0.1:6377`,数据库编号 2 +- PHP-FPM:`127.0.0.1:9000` +- API Nginx:`127.0.0.1:8000` +- Admin Nginx:`127.0.0.1:5176` +- H5 Nginx:`127.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`: + +```bash +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 配置健康检查。部署后至少执行: + +```bash +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: + +```bash +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. 回滚 + +回滚前必须确认生产工作区没有人工修改: + +```bash +git status --short +``` + +切换到已知正常提交并重新构建: + +```bash +git switch --detach <正常提交ID> +sudo docker compose -f docker/docker-compose.prod.yml up -d --build +``` + +恢复跟踪生产分支: + +```bash +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` 拉取并部署。