Files
ai-kefu-jc/docs/deploy-production.md
T
浅念 ae812d9932 docs: 清理已完成待办
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-30 14:29:35 +08:00

201 lines
9.0 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-09-30 · 对应线上版本 `5d83dd9`
> 本文记录**实际部署状态**(不是理想方案),排查问题和重新部署都以此为准。
## 1. 线上环境总览
| 项 | 值 |
|---|---|
| 目标服务器 | 阿里云 ECS(境外)`47.254.176.10`,Debian 13,Docker 29.4.0,1Panel 面板 |
| 跳板机 | 国内阿里云 `8.152.213.143`(境外机直连不通,必须经跳板) |
| 线上域名 | `https://chat2.agent.hnxinyouhe.com`(1Panel 建站,HTTPS 证书已绑定) |
| 应用容器 | `hs-ai-kefu`(端口 `8017:8000`,内存限额 512M) |
| 代码位置 | `/opt/1panel/www/sites/chat2.agent.hnxinyouhe.com/index`(git clone 自公司 git) |
| git 仓库 | `http://219.157.255.213:25311/xinyouhe/ai-kefu-jc.git` |
**同服务器共存的其它项目(部署/排障时绝对不要碰)**:
汽车客服 `cc-ai-kefu`(`chat.agent.hnxinyouhe.com`,端口 8016)、tracker 系列、
photo-live 系列、php7433 等。本项目与它们仅共享 Docker 守护进程,容器/端口/目录/数据完全隔离。
## 2. SSH 连接方式(专属密钥 + 跳板链路)
本机 `~/.ssh/config` 已配好两个别名(密钥为本项目专属 `~/.ssh/ai_kefu_jc_deploy`,
吊销 = 删服务器 `~/.ssh/authorized_keys` 中带 `ai-kefu-jc-deploy` 注释的行):
```
Host ai-kefu-jc-bastion # 跳板(国内)
HostName 8.152.213.143 / User root / Port 22
Host ai-kefu-jc-prod # 目标(境外,经跳板)
HostName 47.254.176.10 / User root / Port 22
ProxyJump ai-kefu-jc-bastion
```
```bash
ssh ai-kefu-jc-prod 'echo ok' # 一键直达到目标服务器
```
## 3. 服务器上的实际布局
```
/opt/1panel/www/sites/chat2.agent.hnxinyouhe.com/
├── index/ ← 项目根(git 仓库,即部署目录)
│ ├── app/ static/ tests/ ...
│ ├── docker-compose.yml ← 注意:服务器上有本地改动(mem_limit 512m,未提交)
│ ├── deploy.sh ← 同上(本地改动)
│ ├── data/hesupipe_ai_kefu.db ← 生产 SQLite(容器卷挂载,gitignore)
│ └── .env ← 生产配置(gitignore,权限600)
├── log/ ← 站点访问日志
├── ssl/ ← HTTPS 证书(1Panel 管理)
└── proxy/ ← 反代配置(1Panel 站点的 include 加载)
├── root.conf ← HTTP 全站反代 → 127.0.0.1:8017
└── ws.conf ← WebSocket 专用路由(与汽车客服同款)
```
1Panel 主配置:`/opt/1panel/www/conf.d/chat2.agent.hnxinyouhe.com.conf`
(其中第 19 行 `include /www/sites/chat2.agent.hnxinyouhe.com/proxy/*.conf;`
是部署时手工补的 —— **1Panel 建站默认不带 include,面板配的反代不会生效**,
备份在同目录 `*.conf.bak.20260930`)。
### 反代实际生效配置(排查时对照)
`proxy/root.conf`(HTTP):
```nginx
location ^~ / {
proxy_pass http://127.0.0.1:8017;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
}
```
`proxy/ws.conf`(WebSocket 专用,`/ws/` 前缀优先命中):
```nginx
location /ws/ {
proxy_pass http://127.0.0.1:8017;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
```
> ⚠️ 反代改动后要重载:`docker exec $(docker ps --filter name=openresty -q | head -1) nginx -t && nginx -s reload`
> (先 `-t` 语法检查再 reload;reload 是平滑的,不影响其他站点)
## 4. 生产 .env(结构,值脱敏)
```ini
AI_PROVIDER=glm
ZHIPU_API_KEY=<与汽车项目同一个>
AI_MODEL=glm-4-flash
ZHIPU_BASE_URL=<同汽车项目>
DATABASE_URL=sqlite+aiosqlite:///./data/hesupipe_ai_kefu.db
SMTP_HOST/PORT/USER/PASS=<真实发件账号,同汽车项目>
NOTIFY_EMAIL=hesu@hesuu.com # 询盘通知收件箱
PUSH_ENABLED=false # 暂不推送 UniService(需求方决定)
PUSH_API_URL=https://uniservice.server.hnxinyouhe.com/open/v1/inquiry/push
PUSH_API_KEY=<已备好,开启时用>
PUSH_EXTERNAL_KEY_PREFIX=ai-kefu-jc # 与汽车项目线索键隔离,勿改!
APP_HOST=0.0.0.0
APP_PORT=8017
APP_DEBUG=false
```
凭据来源:部署时从汽车项目服务器上的 `.env`(`chat.agent.hnxinyouhe.com/index/.env`)
提取同类键,**只读未动**。
## 5. 部署 / 更新流程(日常发版照此执行)
```bash
# 0. 本地:测试全绿才发版
python -m pytest -q # 231 项
# 1. 本地:推送
git push origin master
# 2. 服务器:更新并重建(一条命令)
ssh ai-kefu-jc-prod '
cd /opt/1panel/www/sites/chat2.agent.hnxinyouhe.com/index
git pull
docker compose build && docker compose up -d
sleep 3 && curl -s http://127.0.0.1:8017/health
'
```
说明:
- 静态文件(widget.js 等)**打进镜像**,改前端必须 `build`(仅 `up -d` 不够)
- `.env` 和 `data/` 不在 git 里,更新不受影响
- 回滚:`git checkout <上一版本> && docker compose build && docker compose up -d`
## 6. 验证清单(发版后必跑)
```bash
# ① 健康
curl -s https://chat2.agent.hnxinyouhe.com/health # {"status":"ok"}
# ② 页面
curl -s https://chat2.agent.hnxinyouhe.com/ | grep -o "<title>.*</title>"
# ③ WebSocket(期待 HTTP/1.1 101)
curl -s -i --http1.1 -H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-WebSocket-Version: 13" \
https://chat2.agent.hnxinyouhe.com/ws/chat | head -1
# ④ 静态与缓存头
curl -sI https://chat2.agent.hnxinyouhe.com/static/widget.js | grep -i "cache\|HTTP"
```
功能级验证(改前端/挂件后):打开
`https://chat2.agent.hnxinyouhe.com/static/widget-test.html`,
用 Playwright 或肉眼核对:邀请卡 5 秒弹出位置、面板四个方位(data-position)、
头像加载、主题色断言面板 9/9 绿。
## 7. 本次上线踩坑实录(排查手册)
| 现象 | 根因 | 解法(已内置,重蹈覆辙时对照) |
|---|---|---|
| **两个客服互斥:起一个、另一个 502** | 1Panel 站点目录都叫 `index`,compose 默认以目录名为项目名 → 与汽车项目**同属 project "index"**,任一目录 down/up 会互删对方容器 | compose 固定专属项目名 `name: hs-ai-kefu`(3db3e5b),已重演事故操作验证互不影响 |
| WS 握手 426(HTTP 正常) | 1Panel 面板生成的反代里 `Upgrade/Connection` 头**重复定义两套**,uvicorn 严格解析直接拒绝 | 拆分 ws.conf 单套路(§3),`nginx -T` dump 最终配置 + 假后端 dump 收到的头可快速定位 |
| 改了 widget.js 线上"没生效" | 响应无 Cache-Control,浏览器启发式缓存旧脚本 | 已加中间件 `/static/* → Cache-Control: no-cache`(ec2d17b);用户端 Ctrl+F5 一次即愈 |
| bottom-left 弹出元素溢出屏幕(面板 x=-183) | 弹出层(chat-panel / invite-container)CSS 硬编码 `right:0` 只适配右下角 | 已随 `pos-<position>` 类联动(5d83dd9),静态测试锁死;**新增弹出元素时必须同时加联动规则** |
| 1Panel 配了反代不生效 | 面板建站的主 conf 默认不含 `include proxy/*.conf` | 手工补 include 行(§3),备份后 reload |
| ~~deploy 时 `git pull` 报本地改动冲突~~ | 服务器 compose/deploy.sh 曾有本地改动(mem_limit) | **已正式入 git**(3db3e5b),服务器工作区保持干净,pull 不再需要 stash |
## 8. 常见运维操作
```bash
# 看应用日志(最近100行)
ssh ai-kefu-jc-prod 'docker logs hs-ai-kefu --tail 100'
# 重启应用(不动其他容器)
ssh ai-kefu-jc-prod 'cd /opt/1panel/www/sites/chat2.agent.hnxinyouhe.com/index && docker compose up -d --force-recreate'
# 容器状态/内存
ssh ai-kefu-jc-prod 'docker stats hs-ai-kefu --no-stream'
# 破防率观测(上线第一周必做,见 CLAUDE.md 观察期)
ssh ai-kefu-jc-prod 'docker exec hs-ai-kefu python scripts/breach_rate.py'
# 管理后台
https://chat2.agent.hnxinyouhe.com/admin # 密码在生产 .env 同汽车项目口径
```
## 9. 待办与提醒
- [ ] 官网嵌入:hesupipe.com 按 `docs/embed-guide.md`(script src 用
`https://chat2.agent.hnxinyouhe.com/static/widget.js`,位置/配色/邮箱可配)
- [ ] 邮件通道冒烟:跑一轮测试留资,确认 hesu@hesuu.com 能收到询盘邮件
(单邮件通道,SMTP 失败不自动补发,上线头几天盯收件)
- [ ] 开启 UniService 推送(届时只改 `.env` 的 `PUSH_ENABLED=true` 并重启容器)
- [ ] 上线第一周:跑 breach_rate 观测漏放/误杀(已知 4 项残差见 docs/test-checklist.md)