Files
yunke/docs/DEPLOY.md
T
浅念 35bfebd3e3 chore(backend): list_order迁移补齐+Task14类型修正落链+moments每页日志+MsgTypeParam派生+3处文档修正+Dockerfile打包migrations+DEPLOY补迁移步骤
- 9b0d0c133035: wechat_account.list_order 进迁移链(此前仅模型声明,
  干净库 /api/accounts 即 500);sa.inspect 幂等守卫兼容已手动加列的
  smoke.db
- fe63c6789e94(验证中发现的预存缺口,超出原清单): Task 14 的 5 列模型
  类型修正(4×URL String(1024)→Text, db_size Integer→BigInteger)从未落
  链——纯 alembic 新库会复活 >1KB 链接截断;对齐后干净库 alembic check
  全绿。SQLite message 表 batch 重建会掉 FTS 触发器+rowid 脱节(docstring
  记明 ensure_fts+rebuild_fts 修复,smoke.db 已修复验证)
- scrape_via_page: _iter_moments_pages 每页一行进度日志(镜像 _fetch_pages)
- messages: MsgTypeParam=Literal[tuple(_MSG_TYPE_FILTER)] 派生,杜绝
  双处罗列漂移(openapi enum 验证一致,492 绿含 422 行为)
- 文档: ChatGroup 复合PK docstring/groups room_id 多行表述/测试名去
  单行假设;Dockerfile 补 alembic.ini+migrations;DEPLOY 增「数据库
  迁移」节(新库/旧库stamp路径/回填脚本显式DB_URL)+运维表升级行

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-25 20:32:25 +08:00

173 lines
6.7 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.
# 云客数据镜像 — 服务器部署指南
> 2026-08-21|适用于 Linux 服务器 + Docker Compose 五服务部署
## 架构
```
┌─────────────────────────────────────────────────┐
│ Docker Compose │
│ ┌────────┐ ┌────────┐ ┌────────────────────┐ │
│ │ MySQL 8│ │ Redis 7│ │ backend (FastAPI) │ │
│ │ :3306 │ │ :6379 │ │ :8000 │ │
│ └────┬───┘ └────┬───┘ └─────────▲──────────┘ │
│ │ │ │ /api │
│ ┌────▼───────────▼───┐ ┌────────┴──────────┐ │
│ │ scheduler │ │ frontend (nginx) │ │
│ │ APScheduler │ │ :5173 → :80 │ │
│ │ + Playwright │ └───────────────────┘ │
│ │ + Chromium │ │
│ └────────────────────┘ │
└─────────────────────────────────────────────────┘
```
- **scheduler**:每晚 02:00 全量 + 每 4h 消息增量 + 每周日 05:00 全量对齐(全部浏览器 fetch 零风控)→ 需要 Playwright + Chromium(镜像已内置)
- **restart: unless-stopped**:容器崩溃自动重启(服务器上的守护方案,无需本地计划任务)
## 前置要求
- Linux 服务器(2C4G 起步,磁盘 ≥ 20GB:MySQL 数据 + 媒体文件 2.5GB+)
- Docker 24+ 与 Docker Compose v2
- 一个有效的云客会话 cookie(从浏览器登录云客后复制)
## 部署步骤
### 1. 上传代码
```bash
git clone <你的仓库地址> yunke
cd yunke
```
### 2. 配置 .env
```bash
cp yunke-server/.env.example .env # 或手动创建
```
必须设置的项:
```ini
# 云客会话(从浏览器 F12 → Network → 任意请求的 Cookie 头复制)
YK_USERID=<32位userId>
YK_COMPANY=<公司码>
YK_COOKIE=user=xxx; userToken=yyy
# MySQL(docker-compose 自动创建库和用户)
MYSQL_ROOT_PASSWORD=<强密码>
MYSQL_PASSWORD=<强密码>
# 查看后台的访问令牌(留空=无鉴权,仅限内网)
API_TOKEN=<随机长字符串>
```
### 3. 启动
```bash
docker compose --env-file .env up -d --build
```
首次构建约 5-10 分钟(含 Chromium 下载 ~150MB)。启动后:
```bash
docker compose ps # 五服务全部 Up(healthy)
docker compose logs -f scheduler # 看调度器日志
```
### 4. 数据库迁移(alembic schema)
后端启动**不会**自动建表,schema 由 alembic 迁移链管理(镜像已打包
`alembic.ini` + `migrations/`,`DB_URL` 由 compose 注入)。
**新库首次部署**(空 MySQL 直接建全量表):
```bash
docker compose exec backend alembic upgrade head
```
**旧库升级**(2026-08-22 `migrate_sqlite_to_mysql.py` 搬迁产物,没有
alembic_version 表)——2026-08-25 实战踩通的完整路径,原样记录:
```bash
# 1) 前置校验:chat_group 无 NULL owner_account_id(复合 PK 迁移要求 NOT NULL,
# 非 0 则是必须人工核对的数据问题,不要带病升级)
docker compose exec mysql mysql -uyunke -p<密码> yunke \
-e "SELECT COUNT(*) FROM chat_group WHERE owner_account_id IS NULL"
# 2) stamp 到搬迁脚本对应的链上位置,再升级到 head
docker compose exec backend alembic stamp d8eee96cd017
docker compose exec backend alembic upgrade head
```
**每次拉新代码后**:
```bash
docker compose exec backend alembic upgrade head
```
涉及存量数据回填的更新另跑回填脚本(幂等,重跑 0 改动;脚本默认连
`./smoke.db`,服务器上须显式传 DB_URL——容器 env 已带,直接透传):
```bash
docker compose exec backend python -c "import asyncio,os; from scripts.backfill_chat_group_fields import main; asyncio.run(main(os.environ['DB_URL']))"
docker compose exec backend python -c "import asyncio,os; from scripts.backfill_msg_types import main; asyncio.run(main(os.environ['DB_URL']))"
```
### 5. 验证
```bash
curl http://localhost:8000/api/health # {"status":"ok"}
curl http://localhost:5173/ # 前端页面
```
### 6. 数据迁移(把本地 SQLite 数据搬到服务器 MySQL)
**方式 A:重抓(推荐,数据最新)**
服务器上手动跑一轮全量:
```bash
docker compose exec scheduler bash
DB_URL="mysql+asyncmy://yunke:<密码>@mysql:3306/yunke" \
bash scripts/full_sync_all.sh
```
耗时 6-12 小时(消息全量翻页),跑完后调度器自动接管日常增量。
**方式 B:SQLite → MySQL 数据搬迁**
把本地 smoke.db 和 media/ 目录传到服务器,用 Python 脚本逐表导:
(如有需要我可以写迁移脚本,~100 行)
### 7. 媒体文件
媒体存在 Docker volume `media_data` 里。本地已有 2.5GB 媒体的话:
```bash
# 本地打包
tar czf media.tar.gz -C yunke-server media/
# 传到服务器后灌入 volume
docker run --rm -v yunke_media_data:/target -v $(pwd):/src alpine \
sh -c "cd /target && tar xzf /src/media.tar.gz --strip-components=1"
```
## 日常运维
| 操作 | 命令 |
|---|---|
| 看调度日志 | `docker compose logs -f scheduler` |
| 手动触发全量 | `docker compose exec scheduler bash scripts/full_sync_all.sh` |
| 换 cookie | 改 `.env` 的 `YK_COOKIE` → `docker compose restart scheduler backend` |
| 备份 MySQL | `docker compose exec mysql mysqldump -uroot -p<密码> yunke > backup.sql` |
| 备份媒体 | `docker run --rm -v yunke_media_data:/data -v $(pwd):/out alpine tar czf /out/media.tgz -C /data .` |
| 升级版本 | `git pull && docker compose up -d --build && docker compose exec backend alembic upgrade head`(回填见「数据库迁移」) |
## 已知注意事项
1. **cookie 过期**:云客会话定期失效,过期后日志出现 `⚠️ cookie 可能已过期` 提示 → 从浏览器重新复制 `YK_COOKIE` 并 restart
2. **首次消息全量很慢**(6-12h),之后增量每轮 15-30 分钟
3. **FTS 搜索**:MySQL 上自动回退 LIKE(暂无全文索引);如搜索量大可在 MySQL 建 FULLTEXT 索引
4. **时区**:容器默认 UTC;调度按容器时区触发(FULL_SYNC_HOUR=2 即 UTC 02:00)。要北京时间可在 compose 加 `TZ: Asia/Shanghai`
5. **服务器需能访问 crm2.yunkecn.com 和 *.oss.yunkecn.com**(抓取 + 媒体下载)