Files
koc-loop/docs/KOC LOOP 私有化部署指南.md
2026-08-11 23:07:26 +08:00

197 lines
7.5 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.
# KOC LOOP 私有化部署指南
本文适用于 `codex/self-hosted-mysql` 分支。目标架构是运维提出的Nginx 代理 + KOC 服务 + MySQL 数据库,并让后台、外部 KOC 领取页和 Agent MCP 都能通过一个公网域名访问。
## 1. 部署形态
| 组件 | 容器 | 作用 | 持久化 |
| --- | --- | --- | --- |
| Nginx | `nginx` | 公网入口、反向代理、托管 KOC 领取页 | 配置随镜像 |
| KOC 服务 | `app` | Next.js 后台、API、MCP、每天 10:00 自动采集 | 上传目录挂载卷 |
| MySQL 8 | `mysql` | 任务、笔记、领取、回填、账号、采集和用户数据 | MySQL 数据卷 |
访问路径:
- `https://你的域名/`:运营后台;
- `https://你的域名/koc/`:外部 KOC 领取和回填;
- `https://你的域名/api/mcp`Agent MCP
- `https://你的域名/api/health`:服务健康检查。
第一版按单实例 KOC 服务设计。MySQL 和上传目录均持久化。以后需要横向扩容时,可以把上传卷换成共享 NAS对象存储接口已与业务代码分离。
## 2. 服务器要求
- Linux 服务器一台,建议至少 4 核、8 GB 内存、100 GB 数据盘;
- Docker Engine 24+
- Docker Compose v2
- 可解析到服务器或负载均衡的公网域名;
- HTTPS 证书由公司网关、负载均衡或 Nginx 统一终止;
- 服务器可以访问飞书 OpenAPI 和正式数据采集 MCP。
服务器只需对公网开放 80/443。MySQL 不映射公网端口。
## 3. 准备代码与环境变量
```bash
git clone ssh://git@gta.gbotai.cn:42001/wufengping/koc-loop.git
cd koc-loop
git checkout codex/self-hosted-mysql
cp .env.self-hosted.example .env.self-hosted
```
编辑 `.env.self-hosted`。必须替换所有 `replace-with-*` 占位值:
| 变量 | 用途 |
| --- | --- |
| `MYSQL_ROOT_PASSWORD` | MySQL root 密码,仅数据库容器使用 |
| `MYSQL_PASSWORD` | KOC 服务的数据库密码 |
| `APP_ORIGIN` | 后台公网地址,如 `https://koc.example.com` |
| `KOC_PORTAL_URL` | 领取页完整地址,如 `https://koc.example.com/koc/` |
| `SUPER_ADMIN_USERNAME` | 首次启动创建唯一超级管理员 |
| `SUPER_ADMIN_PASSWORD` | 首次启动的超级管理员初始密码,至少 8 位 |
| `ADMIN_INTERNAL_TOKEN` | 内部管理调用密钥 |
| `KOC_MCP_API_KEY` | Agent 调用 KOC LOOP MCP 的独立 Bearer 密钥 |
| `FEISHU_APP_ID` / `FEISHU_APP_SECRET` | 读取飞书内容表和配图 |
| `AI_TOOL_CENTER_MCP_URL` / `AI_TOOL_CENTER_MCP_KEY` | 小红书公开数据采集服务 |
| `ENABLE_SCHEDULER` | 是否启用每天 10:00 自动采集,生产保持 `true` |
密钥必须由密码管理器生成,禁止提交到 Git、聊天、部署日志或 URL。三个业务密钥 `ADMIN_INTERNAL_TOKEN``KOC_MCP_API_KEY``AI_TOOL_CENTER_MCP_KEY` 不得复用。
## 4. 首次启动
```bash
docker compose --env-file .env.self-hosted \
-f docker-compose.self-hosted.yml up -d --build
```
应用容器启动时会先执行同一套数据库迁移脚本,成功后才启动 KOC 服务。查看状态:
```bash
docker compose --env-file .env.self-hosted \
-f docker-compose.self-hosted.yml ps
curl -fsS http://127.0.0.1:${HTTP_PORT:-80}/api/health
```
健康检查应返回 `status: ok``database: true`
首次打开后台登录页时,系统会根据环境变量创建唯一超级管理员。创建成功后,可从运行环境移除 `SUPER_ADMIN_PASSWORD` 的明文值并重启应用;后续账号与密码统一在“用户管理”中维护。
## 5. Nginx 与 HTTPS
仓库内 `deploy/nginx/koc-loop.conf` 默认监听容器 80 端口,适合前置公司网关或负载均衡终止 HTTPS。
如果证书直接挂在本机 Nginx
1. 把证书和私钥以只读卷挂载进 `nginx` 容器;
2. 增加 443 `listen ... ssl` 配置;
3. 80 端口只做 301 跳转;
4. 保留 `/koc/` 静态规则、`/api/mcp` 长连接规则和 `/` 反向代理规则。
MCP 路由已经关闭代理缓冲并将超时时间延长到 1 小时,避免 Agent 的长调用被 Nginx 提前截断。
## 6. 迁移原 Sites 数据
迁移分为数据库与图片两部分。先在原生产站点保持只读窗口,完成导出后再切换域名,避免新旧系统同时写入。
### 6.1 D1 数据导入 MySQL
把 D1 各表导出成一个 JSON 文件,结构如下:
```json
{
"tables": {
"partners": [{ "id": "...", "name": "..." }],
"tasks": [{ "id": "...", "name": "..." }],
"contents": [],
"accounts": [],
"claims": [],
"delegation_bundles": [],
"distributions": [],
"collection_runs": [],
"users": [],
"auth_sessions": [],
"mcp_export_tokens": []
}
}
```
先确保 MySQL 迁移已完成,再在应用环境中运行:
```bash
npm run db:import-json -- /backup/koc-d1-export.json
```
导入脚本按业务依赖顺序写入,并使用主键/唯一键安全更新已有记录。正式迁移前先在测试库演练并核对任务数、笔记数、领取数、发布数和账号数。
### 6.2 R2 图片导入
把 R2 按原对象 key 导出到一个目录,目录层级必须保留,例如:
```text
content-assets/...
publish-evidence/...
creator-center/...
```
运行:
```bash
UPLOAD_DIR=/data/koc/uploads \
npm run storage:import -- /backup/koc-r2-export
```
脚本会复制文件,并为缺少元数据的图片生成 Content-Type 元数据。容器部署时也可以在宿主机临时挂载 `upload_data` 卷后执行。
## 7. 上线验收
必须逐项验证:
1. 超级管理员可以登录,普通用户看不到 KOC 资源模块;
2. 用真实飞书表格创建一个 1 篇测试任务;
3. 返回的领取链接以 `/koc/?task=` 开头;
4. 手机公网打开领取页,能查看正文与配图;
5. 回填短链/长链、上传发布截图、刷新后记录仍在;
6. 上传创作者截图并填写曝光量、阅读量;
7. 后台立即采集一篇笔记成功;
8. 保存次日采集计划,确认数据库产生 `collection_runs`
9. 导出的 Excel 内能直接看到原图和截图;
10. Agent 用 `KOC_MCP_API_KEY` 调用 `/api/mcp` 能发现全部工具;
11. 重启全部容器后数据与图片不丢失。
## 8. 备份与恢复
每天至少备份:
- MySQL`mysqldump --single-transaction`
- `mysql_data` 卷;
- `upload_data` 卷;
- 当前 Git 提交号和脱敏后的环境变量清单。
备份必须复制到另一台机器或对象存储,不能只保存在部署服务器。恢复演练至少每季度一次。
## 9. 升级与回滚
升级前先备份数据库和上传卷:
```bash
git pull
docker compose --env-file .env.self-hosted \
-f docker-compose.self-hosted.yml up -d --build
```
数据库迁移只允许向前追加新的 `mysql/*.sql` 文件,禁止修改已经在生产执行过的迁移。应用回滚到旧镜像前,要确认旧代码兼容当前数据库结构;涉及不可逆结构变化时,必须同时准备数据库恢复方案。
## 10. 运维排查
| 现象 | 处理 |
| --- | --- |
| `/api/health` 返回 503 | 查看 MySQL 容器健康状态与应用数据库变量 |
| 登录页可开但登录失败 | 确认迁移完成、超级管理员变量仅用于初始化 |
| 配图或截图 404 | 检查 `upload_data` 卷和 `UPLOAD_DIR=/data/koc/uploads` |
| 10:00 未自动采集 | 检查 `ENABLE_SCHEDULER=true`、服务器日志和采集 MCP 网络 |
| MCP 401 | 检查请求头是否为 `Authorization: Bearer <KOC_MCP_API_KEY>` |
| 飞书读取失败 | 检查应用权限、文档授权和服务器到飞书 OpenAPI 的网络 |
生产日志不得打印数据库密码、飞书 Secret、MCP key 或完整带 key 的采集服务 URL。