Files
zhuiguang-ai/.trae/specs/modules/09-devops.md
T

155 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 运维与部署模块
## 服务器与基础设施
### 环境信息
- **域名**: www.zhuig.com (HTTPS,SSL证书自动续期)
- **云服务器**: 119.45.242.239 (登录名: ubuntu, 密钥: E:\ZG_Dev\pem\zg.pem)
- **数据库**: 阿里云RDS MySQL — rm-0jlbgr2rv6dj3t6jngo.mysql.rds.aliyuncs.com:3306
- **Redis**: Docker容器redis-cache:6379,有密码认证
- **开发机**: E:\ZG_Dev\ZhuiGuangAI\zhuiguang-ai
- **部署目录**: /home/ubuntu/zhuiguang-ai
- **访问地址**: https://www.zhuig.com (HTTP自动跳转HTTPS)
- **本地Git同步目录**: C:\gitbf (完整Git仓库)
### 端口规范
- **应用端口范围**: 8301-8310(预留扩展)
- **默认端口**: 8301
- **重启脚本**: 仅扫描8301-8310范围
- **强制要求**: 本项目端口必须锁定在8301-8310区间内,禁止使用其他端口
## Nginx配置
- 文件: `nginx.conf`
- HTTPS反向代理到本地8301端口
- HTTP自动跳转HTTPS
- SSL证书自动续期
## 部署流程
### 本地开发
```bash
# 1. 安装依赖
npm install
# 2. 配置环境变量
# 编辑 .env 文件
# 3. 数据库迁移
npx prisma migrate dev
# 4. 启动开发服务器
npm run dev
# 或重启
pwsh -ExecutionPolicy Bypass -File restart.ps1
```
### 服务器部署
```bash
# 1. SSH到服务器
ssh -i E:\ZG_Dev\pem\zg.pem ubuntu@119.45.242.239
# 2. 进入部署目录
cd /home/ubuntu/zhuiguang-ai
# 3. 拉取最新代码
git pull
# 4. 安装依赖
npm install
# 5. 数据库迁移
npx prisma migrate deploy
# 6. 构建生产版本
npm run build
# 7. 重启服务
pm2 restart zhuiguang-ai
```
## 定时任务 (Crontab)
### Crontab配置
- 用户: ubuntu
- 查看: `crontab -l`
- 编辑: `crontab -e`
### 任务列表
| 时间 | 任务 | 脚本 | TaskKey | 说明 |
|------|------|------|---------|------|
| 01:00 | Task5 更新星值 | `scripts/task5-update-stars.mjs` | task5-update-stars | 更新所有GitHub技能Stars数+日/周/月变化 |
| 03:00 | Task3 工具巡检 | `scripts/task3-check-tools.mjs` | task3-check-tools | 检查网站/Logo可访问性+自动发布合格待审核工具 |
| 04:00 | Task6 评测热门 | `scripts/task6-review-hot.mjs` | task6-review-hot | 评测2个最热未评测GitHub技能(五维评测) |
| 05:00 | Task4 发现技能 | `scripts/daily-discover.mjs` | task4-discover-skills | GitHub搜索≥1000 stars项目→DeepSeek预评测→入库PendingSkill |
| 06:00 | Task1 发现工具 | `scripts/task1-discover-tools.mjs` | task1-discover-tools | 36kr/IT之家/开源中国RSS→DeepSeek提取工具→入库PendingTool |
| 07:30 | AI日报 | `scripts/daily-news.mjs` | daily-news | 多源搜索真实新闻+DeepSeek整理格式→发布日报 |
### 日志目录
- 路径: `/home/ubuntu/zhuiguang-ai/logs/`
- 文件: task1.log ~ task6.log
### 任务执行原理
1. Crontab定时触发脚本执行
2. 脚本调用外部API(GitHub/DeepSeek/网站)
3. 数据写入数据库(Tool/Skill/PendingTool/PendingSkill/DailyReport)
4. TaskLog表记录执行结果(status/duration/result/error)
5. 后台管理页面可视化管理(/admin/tasks)
6. 支持手动触发(POST /api/admin/tasks/run)
## 环境变量
### .env配置
```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 模型名(可选,默认 deepseek-v4-pro)
DEEPSEEK_MODEL="deepseek-v4-pro"
```
> **注意**: `.env` 文件已被加入 `.gitignore`,不得提交到 Git 仓库。请使用 `.env.example` 作为模板。
## PM2配置
- 进程名: zhuiguang-ai
- 启动命令: `npm run start`
- 端口: 8301
- 重启: `pm2 restart zhuiguang-ai`
## 安全配置
### 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()
- 服务器环境SSL证书问题: 运行脚本需设置$env:NODE_TLS_REJECT_UNAUTHORIZED="0"
- Chart.js font.weight只接受bold/normal/bolder/lighter,不接受数字字符串如"500"