# 运维与部署模块 ## 服务器与基础设施 ### 环境信息 - **域名**: www.zhuig.com (HTTPS,SSL证书自动续期) - **云服务器**: 119.45.242.239 (登录名: ubuntu, 密钥: `C:\SGP_KF\ZhuiGuangAI\zhuiguang-ai\Pem\zg.pem`) - **数据库**: 阿里云RDS MySQL — rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306 - **Redis**: Docker容器 redis-cache:6379,有密码认证(共享服务) - **Nacos**: Docker容器 nacos:8848(共享服务) - **MinIO**: Docker容器 minio:9000(共享服务) - **部署目录**: /home/ubuntu/zhuiguang-ai - **访问地址**: https://www.zhuig.com (HTTP自动跳转HTTPS) - **本地Git同步目录**: C:\gitbf ### 端口规范 - **应用端口范围**: 8301-8310(预留扩展) - **默认端口**: 8301 - **强制要求**: 本项目端口必须锁定在8301-8310区间内,禁止使用其他端口 --- ## 容器化部署架构 ### 容器清单 | 容器名 | 镜像 | 端口 | 用途 | |--------|------|------|------| | `zhuiguang-ai-app` | `zhuiguang-ai:latest` | 8301 | Next.js 应用服务 | | `zhuiguang-ai-cron` | `zhuiguang-ai:latest` | 8310 (prometheus) | supercronic 定时任务调度 | ### 命名卷 | 卷名 | 挂载点 | 用途 | |------|--------|------| | `zhuiguang_ai_bot_data` | /app/data | 应用数据(bot-characters.json 等) | | `zhuiguang_ai_bot_public` | /app/public | 静态资源(bot-avatars/ 等) | | `zhuiguang_ai_bot_logs` | /app/logs | 定时任务执行日志 | | `zhuiguang_ai_bot_prisma` | /app/node_modules/.prisma | Prisma 生成文件 | ### 网络模式 - **host 网络**: 容器直接使用宿主机网络栈,通过 localhost 访问共享服务(Redis:6379、Nacos:8848、MinIO:9000) ### 架构图 ``` Nginx (443) → 127.0.0.1:8301 → zhuiguang-ai-app (Docker, host 网络) Cron → zhuiguang-ai-cron (Docker, supercronic, host 网络) 共享卷: data / public / logs / prisma (命名卷) 外部: 阿里云 RDS / 共享 Redis / 共享 Nacos / 共享 MinIO ``` --- ## Nginx配置 - 文件: `/etc/nginx/sites-enabled/zhuiguang-ai` - HTTPS反向代理到本地8301端口 - HTTP自动跳转HTTPS - SSL证书自动续期 - **注意**: Nginx 始终代理 `127.0.0.1:8301`,切换 PM2→Docker 时无需改动 --- ## 部署流程 ### 本地开发 ```bash # 1. 安装依赖 npm install # 2. 配置环境变量 # 编辑 .env 文件 # 3. 数据库迁移 npx prisma migrate dev # 4. 启动开发服务器 npm run dev ``` ### 生产构建 + 部署 ```bash # 1. 构建镜像 cd /home/ubuntu/zhuiguang-ai docker build -t zhuiguang-ai:latest . # 2. 停止旧容器 docker stop zhuiguang-ai-app zhuiguang-ai-cron docker rm zhuiguang-ai-app zhuiguang-ai-cron # 3. 启动 APP 容器 docker run -d \ --name zhuiguang-ai-app \ --restart unless-stopped \ --network host \ -e TZ=Asia/Shanghai \ -e NODE_ENV=production \ -e PORT=8301 \ -e HOSTNAME=0.0.0.0 \ -v /home/ubuntu/zhuiguang-ai/env/.env.production:/app/.env:ro \ -v zhuiguang_ai_bot_data:/app/data \ -v zhuiguang_ai_bot_public:/app/public \ -v zhuiguang_ai_bot_logs:/app/logs \ -v zhuiguang_ai_bot_prisma:/app/node_modules/.prisma \ zhuiguang-ai:latest # 4. 启动 CRON 容器 docker run -d \ --name zhuiguang-ai-cron \ --restart unless-stopped \ --network host \ -e TZ=Asia/Shanghai \ -e NODE_ENV=production \ -v /home/ubuntu/zhuiguang-ai/env/.env.production:/app/.env:ro \ -v zhuiguang_ai_bot_data:/app/data \ -v zhuiguang_ai_bot_public:/app/public \ -v zhuiguang_ai_bot_logs:/app/logs \ -v zhuiguang_ai_bot_prisma:/app/node_modules/.prisma \ -v /home/ubuntu/zhuiguang-ai/crontab.txt:/app/crontab.txt:ro \ zhuiguang-ai:latest /usr/local/bin/entrypoint-cron.sh # 5. 验证 docker ps --filter name=zhuiguang-ai curl -I http://localhost:8301/ ``` ### 使用 docker-compose(推荐) ```bash cd /home/ubuntu/zhuiguang-ai docker-compose down docker-compose build docker-compose up -d ``` ### 测试部署(端口 8302,与生产并行) ```bash cd /home/ubuntu/zhuiguang-ai docker-compose -f docker-compose.test.yml down docker-compose -f docker-compose.test.yml build docker-compose -f docker-compose.test.yml up -d ``` --- ## Docker 镜像构建 ### Dockerfile 结构 ``` 阶段 1: deps — npm ci 安装依赖(含 devDependencies) 阶段 2: builder — prisma generate + npm run build 阶段 3: runner — 仅复制生产依赖 + 构建产物,最终镜像 ~1.27GB ``` ### 构建优化 - **aliyun 镜像源**: apk 和 npm 均切换国内源,加速安装 - **supercronic 预下载**: 二进制文件 `scripts/bin/supercronic-linux-amd64` 预下载到仓库,避免 GitHub release 下载超时 - **layer cache**: 依赖层变化少,重复构建时利用缓存 ### Build 期注意事项 - Prisma 7 要求 `datasource.url` 在 `prisma.config.ts` 中,不能在 `schema.prisma` 中 - Next.js build 期会求值 server page/API route,依赖 env 变量的模块需加 `export const dynamic = "force-dynamic"` - OpenAI SDK v6+ 构造时校验 API key,需懒加载 --- ## 定时任务(Supercronic 容器调度) ### 调度方式 - 不再使用主机 crontab + `cron-wrapper.sh` - 由 `zhuiguang-ai-cron` 容器内 supercronic 调度 - 配置文件: `crontab.txt`(项目根目录) - 修改 crontab.txt 后需重建 cron 容器生效 ### 任务列表(25 条) | 时间 | 任务 | 脚本 | |------|------|------| | 01:00 | Task5 更新星值 | `scripts/task5-update-stars.mjs` | | 02:00 | Bot 技能结晶 | `scripts/bot-skill-crystallize.mjs` | | 03:00 | Task3 工具巡检 | `scripts/task3-check-tools.mjs` | | 04:00 | Task6 评测热门 | `scripts/task6-review-hot.mjs` | | 05:00 | Bot 亲和度与画像 | `scripts/bot-affinity-update.mjs` | | 05:00 | Task4 发现技能 | `scripts/daily-discover.mjs` | | 06:00 | Task1 发现工具 | `scripts/task1-discover-tools.mjs` | | 07:30 | AI日报 | `scripts/daily-news.mjs` | | 08:00 | Task7 新闻推社区 | `scripts/task7-news-to-community.mjs` | | 09:00-23:00 | Bot 活动引擎 | `scripts/bot-activity.mjs`(每小时) | | 21:30 | Bot 反馈闭环 | `scripts/bot-feedback-loop.mjs` | | 周日 22:30 | Bot 跨板块亲和度 | `scripts/bot-affinity-update.mjs` | | 周日 02:00 | Bot 周度复盘 | `scripts/bot-weekly-review.mjs` | ### 日志目录 - 容器内路径: `/app/logs/`(挂载到 Docker volume `zhuiguang_ai_bot_logs`) - 查看日志: `docker logs zhuiguang-ai-cron` 或 `docker exec zhuiguang-ai-cron cat /app/logs/bot-activity.log` --- ## 容器运维命令 ### 状态查看 ```bash # 容器状态 docker ps --filter name=zhuiguang-ai # 容器健康状态 docker inspect zhuiguang-ai-app --format '{{.State.Health.Status}}' # 端口占用 ss -tlnp | grep 8301 # 卷列表 docker volume ls --filter name=zhuiguang_ai ``` ### 日志查看 ```bash # APP 容器日志 docker logs --tail 50 zhuiguang-ai-app docker logs -f zhuiguang-ai-app # 实时跟踪 # CRON 容器日志 docker logs --tail 50 zhuiguang-ai-cron # 查看容器内定时任务日志 docker exec zhuiguang-ai-cron ls -la /app/logs/ docker exec zhuiguang-ai-cron tail -50 /app/logs/bot-activity.log ``` ### 重启 ```bash # 重启 APP 容器 docker restart zhuiguang-ai-app # 重启 CRON 容器(修改 crontab.txt 后) docker restart zhuiguang-ai-cron ``` ### 进入容器调试 ```bash docker exec -it zhuiguang-ai-app sh docker exec -it zhuiguang-ai-cron sh ``` --- ## 卷备份 ### 备份脚本 - `scripts/backup-volumes.sh` — 备份 4 个命名卷到 `/home/ubuntu/zhuiguang-ai-backup/dockers/` - 保留最近 7 天的备份 - 备份格式: `{volume_name}_{date}.tar.gz` ### 主机备份 cron - `scripts/install-cron-backup.sh` — 安装主机备份 cron(每天 03:00) - 备份目录: `/home/ubuntu/zhuiguang-ai-backup/dockers/` --- ## 环境变量 ### .env.production 配置 ```bash # 数据库(必填) DATABASE_URL="mysql://mohe001:***@rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306/zhuiguang_ai?charset=utf8mb4" # NextAuth(必填) NEXTAUTH_URL="http://localhost:8301" NEXTAUTH_SECRET="请生成一个随机高强度密钥(至少32位)" # GitHub API(必填,提升限流60→5000次/小时) GITHUB_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx" # DeepSeek API(必填) DEEPSEEK_API_KEY="sk-..." DEEPSEEK_MODEL="deepseek-v4-pro" # OpenAI API(Bot 活动引擎使用) OPENAI_API_KEY="sk-..." ``` > **注意**: 容器运行时 `.env` 文件以只读方式挂载(`:ro`),避免容器内误修改。 --- ## 安全配置 ### HTTP 响应头 next.config.mjs 配置以下安全响应头: - **CSP (Content-Security-Policy)**: `default-src 'self'` + 安全白名单 - **HSTS (Strict-Transport-Security)**: `max-age=31536000; includeSubDomains` - **Permissions-Policy**: `camera=(), microphone=(), geolocation=()` - **X-Content-Type-Options**: `nosniff` - **X-Frame-Options**: `DENY` - **X-XSS-Protection**: `1; mode=block` - **Referrer-Policy**: `strict-origin-when-cross-origin` ### 权限控制 - middleware.ts 中 `/admin/*` 和 `/api/admin/*` **仅 admin 角色可访问**(VIP 用户无权限) --- ## 踩坑记录 - Next.js 14不支持useActionState,登录页用原生表单POST - Prisma MariaDB adapter需要连接字符串方式初始化 - 图片域名需在next.config.mjs中配置remotePatterns - 热重载后需清除.next缓存: 删除.next目录后重启 - Chart.js组件需用dynamic import + ssr: false,不支持服务端渲染 - Prisma 7.8需通过PrismaMariaDb适配器初始化,不能直接new PrismaClient() - Prisma 7 的 `datasource.url` 必须放在 `prisma.config.ts` 中,不能在 `schema.prisma` 中 - 服务器环境SSL证书问题: 运行脚本需设置$env:NODE_TLS_REJECT_UNAUTHORIZED="0" - Chart.js font.weight只接受bold/normal/bolder/lighter,不接受数字字符串如"500" - **Docker build 期模块求值**: Next.js build 时会预渲染 server page 和 API route,导致 Prisma/OpenAI 等模块被求值。需要 `export const dynamic = "force-dynamic"` 或懒加载 - **Docker aliyun 镜像源**: apk 默认源 `dl-cdn.alpinelinux.org` 极慢(1m23s),切换 `mirrors.aliyun.com` 仅需 0.134s;npm 切换 `registry.npmmirror.com` - **Supercronic 下载**: GitHub release 的 `release-assets.githubusercontent.com` 在服务器上可能超时,建议预下载二进制到仓库 - **Docker host 网络**: 使用 host 网络模式才能让容器内进程通过 localhost 访问共享服务(Redis、Nacos、MinIO) --- ## 开发规则引用 > 运维和部署必须遵守以下规则: > - [第十四章 - Docker容器规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):容器清单(app+cron)、host网络、健康检查、容器管理命令 > - [第十五章 - 部署规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):部署前5项自检、构建流程、部署后六项验证、镜像回滚策略 > - [第八章 - 定时任务规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):crontab管理四方同步、entrypoint-cron信号处理、备份脚本完整性 > - [第十三章 - Shell脚本规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):set -e、结构化输出、磁盘预检、禁止操作(禁杀共享进程) > - [第十九章 - 环境变量管理规范](file:///c:/SGP_KF/ZhuiGuangAI/zhuiguang-ai/.trae/rules/project_rules.md):变量分级、.env.example同步、脚本侧加载顺序