- docker compose 部署:app / db / redis / tls(nginx) / bridge-tools,宿主端口错开避免与本机服务冲突 - bridge-tools 内联进仓库(compose build 路径改为 ./bridge-tools),仓库自包含可部署 - 部署说明 README、crm-new 对照与 bridge-tools 方案文档、备份与隧道脚本 - .gitignore 排除 .env、config.toml、uploads/、tls 私钥/证书、backups/、logs/
185 lines
11 KiB
Markdown
185 lines
11 KiB
Markdown
# LibreDesk 本地实例(yehwang-ai)
|
||
|
||
按官方文档 [docs.libredesk.io/getting-started/installation](https://docs.libredesk.io/getting-started/installation) 的 Docker 方式部署的独立实例,
|
||
与本机 `crm-new` 项目里那套 LibreDesk 完全隔离(独立容器、独立数据卷、独立端口)。
|
||
|
||
## 访问
|
||
|
||
| 项 | 值 |
|
||
| --- | --- |
|
||
| 后台地址 | **https://192.168.31.61:9443**(自签证书,首次需点“继续前往”;见下方「为什么会一直 Connecting」) |
|
||
| API / 直连 | http://localhost:9001(后台界面走这个地址会一直 Connecting,仅用于 API/调试) |
|
||
| 登录账号 | `System` |
|
||
| 登录密码 | `Ld@42d0ef50ac5d0efa`(也存在 `.env` 的 `LIBREDESK_SYSTEM_USER_PASSWORD`,登录后建议改掉) |
|
||
|
||
## 组成
|
||
|
||
| 服务 | 镜像 | 容器名 | 宿主端口 |
|
||
| --- | --- | --- | --- |
|
||
| app | libredesk/libredesk:**v2.9.1**(当前稳定版) | libredesk_app | **127.0.0.1**:9001 → 9000(仅本机/隧道) |
|
||
| db | pgvector/pgvector:pg18(本机已缓存;官方文档默认 postgres:17-alpine,本机拉取该镜像一直失败,见下方「已知偏差」) | libredesk_db | 127.0.0.1:5433 → 5432 |
|
||
| redis | redis:7-alpine | libredesk_redis | 127.0.0.1:6380 → 6379 |
|
||
| tls | nginx:alpine | libredesk_tls | 9443 → 443 |
|
||
| bridge-tools | 本仓库 `./bridge-tools`(Node 24,零依赖) | libredesk_bridge_tools | 127.0.0.1:4101 → 4100(LibreDesk 内部走 `bridge-tools:4100`) |
|
||
|
||
数据:`postgres-data`、`redis-data` 两个 Docker 卷;上传文件在 `./uploads`。
|
||
配置:`config.toml`(含加密密钥与 DB 密码,不入库)、`.env`(含容器密码,不入库)。
|
||
|
||
## 为什么会一直 “Connecting...”
|
||
|
||
现象:用 `http://192.168.31.61:9001` 打开后台,右上角一直显示 `Connecting...`,app 日志反复报:
|
||
|
||
```
|
||
error upgrading tcp connection ... error="websocket: request origin not allowed by FastHTTPUpgrader.CheckOrigin"
|
||
```
|
||
|
||
原因:libredesk v2.9.x 的 Agent 实时通道(`/ws`)在 `cmd/websocket.go` 里做了 Origin 校验,
|
||
**只接受 `https` 或 `localhost` 的 Origin**,`http://<局域网IP>:9001` 一定被 403 拒绝,前端就无限重连。
|
||
|
||
解决:compose 里加了 `tls`(nginx)容器做 HTTPS 终结,后台走 **https://192.168.31.61:9443**。
|
||
证书是自签的(SAN 含 `192.168.31.61`、`127.0.0.1`、`localhost`),首次访问浏览器会告警,点“高级 → 继续前往”即可;
|
||
想彻底不告警,把 [tls/cert.pem](tls/cert.pem) 导入你电脑的“受信任的根证书颁发机构”。
|
||
|
||
另一个等效办法(不动证书):`ssh -L 9001:127.0.0.1:9001 dev@192.168.31.61`,然后开 `http://localhost:9001`
|
||
(Origin 是 localhost,校验放行)。
|
||
|
||
## 常用操作
|
||
|
||
```bash
|
||
cd /home/dev/code/yehwang-ai/libredesk
|
||
|
||
docker compose ps # 状态
|
||
docker compose logs -f app # 日志
|
||
docker compose restart app # 重启
|
||
docker compose down # 停止(保留数据)
|
||
docker compose down -v # 停止并删除数据卷(会丢数据)
|
||
|
||
# 重设 System 用户密码(交互式)
|
||
docker exec -it libredesk_app ./libredesk --set-system-user-password --config /libredesk/config.toml
|
||
|
||
# 升级/切换版本:改 .env 的 LIBREDESK_IMAGE 后 recreate,启动命令会自动跑 --upgrade
|
||
docker compose pull && docker compose up -d
|
||
```
|
||
|
||
## 版本与升级
|
||
|
||
当前版本:**v2.9.1**(2026-10-28 发布的稳定版,替代 v2.9.0)。
|
||
|
||
版本演进:`v2.9.0`(初装)→ `v2.9.1-rc.1`(2026-10-28 15:06)→ `v2.9.1` 正式版(2026-10-28 15:42)。
|
||
每一次升级都只改 `.env` 的 `LIBREDESK_IMAGE` + `docker compose up -d app`,启动命令自动执行 `--install --idempotent-install` 与 `--upgrade`。
|
||
|
||
| 升级 | 迁移 | 说明 |
|
||
| --- | --- | --- |
|
||
| v2.9.0 → v2.9.1-rc.1 | 无(`no upgrades to run`) | 48 commits / 14 PR,config.sample.toml 逐字节一致 |
|
||
| v2.9.1-rc.1 → v2.9.1 | 无(`no upgrades to run`) | 仅 2 commits / 1 个前端文件(automation 帮助文案对齐),无 schema 变化 |
|
||
|
||
升级前的备份(都在 [backups/](backups)):
|
||
|
||
| 时间 | DB 备份 | 当时版本 |
|
||
| --- | --- | --- |
|
||
| 2026-10-28 15:02 | [libredesk-v2.9.0-20261028-1502.dump](backups/libredesk-v2.9.0-20261028-1502.dump)(633 TOC 条目) | v2.9.0 |
|
||
| 2026-10-28 15:40 | [libredesk-v2.9.1-rc.1-20261028-1540.dump](backups/libredesk-v2.9.1-rc.1-20261028-1540.dump) | v2.9.1-rc.1 |
|
||
|
||
**回滚**(到目前为止从没跑过迁移,回滚只是切镜像,不动数据):把 `.env` 的 `LIBREDESK_IMAGE` 改成目标版本(如 `libredesk/libredesk:v2.9.0`)再 `docker compose up -d app`。
|
||
只有当某次升级真的执行了迁移时才需要恢复 dump:
|
||
|
||
```bash
|
||
docker compose stop app
|
||
docker compose exec -T db psql -U libredesk -d libredesk -c 'drop schema public cascade; create schema public;'
|
||
docker compose exec -T db pg_restore -U libredesk -d libredesk --no-owner < backups/<对应版本>.dump
|
||
docker compose up -d app
|
||
```
|
||
|
||
v2.9.1 的主要变化:邮件主题/发件人 MIME 解码、IMAP 启动即扫描、`/health` 数据库不可用时返回非 200(已用于 compose 的 app healthcheck)、10 月安全审计的 5 个修复([PR #733](https://github.com/abhinavxd/libredesk/pull/733))、依赖漏洞升级([PR #742](https://github.com/abhinavxd/libredesk/pull/742))、AI 回复期间新消息继续接答、自动分配跳过 away 的 agent、日期筛选月份跳转、自定义属性可点击、automation 模板变量帮助等。详见 [release notes](https://github.com/abhinavxd/libredesk/releases/tag/v2.9.1)。
|
||
|
||
## 当前业务配置(2026-10-28)
|
||
|
||
| 项 | 状态 |
|
||
| --- | --- |
|
||
| AI completion | `qwen-max` @ DashScope(openai 兼容),temperature 0.3、max_tokens 800 |
|
||
| AI embedding | `text-embedding-v4`,1024 维;108 篇帮助文章已嵌入(启动日志 `loaded embeddings into memory count=108`) |
|
||
| 通知邮件 / OTP | 163 SMTP(smtp.163.com:465, TLS),发件人 `Yehwang Support <xx2227234215@163.com>` |
|
||
| 团队 | 「Wholesale Support」,Europe/Berlin,Round robin |
|
||
| 帮助中心 | `yehwang-help`(已启用,9 个分类 / 108 篇文章,已挂 livechat inbox 1) |
|
||
| AI Assistant | 「Yehwang Assistant」,friendly/balanced,max_turns 8,handoff + 引用开启,fallback team = Wholesale Support |
|
||
| AI Tools | `search_products` / `search_orders` / `search_inventory` / `get_customer_info`(后两个 requires_verification) |
|
||
| 渠道 inbox | **Website(livechat)** 已建:id=1,uuid `81b679b0-33fb-4796-9f83-dcc0f43231cc`;email / WhatsApp 待做 |
|
||
| 自动化 | 规则「Assign new conversations to AI Assistant」:新会话 → 分配给 Yehwang Assistant |
|
||
| 站点名 | `Yehwang Support` |
|
||
|
||
> 换 AI 模型时注意:`qwen-plus-latest` 在这套长 prompt 下不调用工具(会凭自身知识乱答并编造引用),已验证 `qwen-max` 正常。
|
||
|
||
## Live Chat 接入(widget)
|
||
|
||
```html
|
||
<script>
|
||
window.LibredeskSettings = {
|
||
baseURL: 'https://192.168.31.61:9443',
|
||
inboxID: '81b679b0-33fb-4796-9f83-dcc0f43231cc'
|
||
};
|
||
</script>
|
||
<script async src="https://192.168.31.61:9443/widget.js"></script>
|
||
```
|
||
|
||
匿名访客即可发起会话;已登录客户可用站点后端签 JWT(`POST /api/v1/widget/chat/auth/exchange`)做身份锚定。
|
||
|
||
## 运维:备份 / 访问控制 / 安全头
|
||
|
||
**备份(已定时)**
|
||
|
||
- 脚本:[scripts/backup.sh](scripts/backup.sh),产物在 [backups/](backups):`db-<ts>.dump`(pg_dump -Fc)、`uploads-<ts>.tar.gz`、`config.toml.<ts>`、`env.<ts>`;
|
||
- 校验:每个 dump 会用 `pg_restore -l` 读出 TOC(当前 629 条),失败则脚本非 0 退出;
|
||
- 保留 **14 天**(`find -mtime +14 -delete`);
|
||
- cron(dev 用户,已安装):`0 3 * * * cd .../libredesk && ./scripts/backup.sh >> logs/backup.log 2>&1`;
|
||
- 恢复演练(已验证过一次:57 张表 / 108 篇文章):
|
||
|
||
```bash
|
||
docker cp backups/db-<ts>.dump libredesk_db:/tmp/restore.dump
|
||
docker compose exec -T db createdb -U libredesk libredesk_restore_test
|
||
docker compose exec -T db pg_restore -U libredesk -d libredesk_restore_test --no-owner /tmp/restore.dump
|
||
docker compose exec -T db psql -U libredesk -d libredesk_restore_test -tAc "select count(*) from help_articles"
|
||
docker compose exec -T db dropdb -U libredesk libredesk_restore_test
|
||
```
|
||
|
||
**访问控制**
|
||
|
||
- `9001`(明文 app)只绑 `127.0.0.1`,局域网只能走 `https://192.168.31.61:9443`;本机/SSH 隧道调试不受影响;
|
||
- nginx 已加 `TLSv1.2/1.3`、`X-Content-Type-Options: nosniff`、`Referrer-Policy`(X-Frame-Options 由应用自己发,避免重复)。
|
||
|
||
### ⚠️ bridge-tools 依赖本机 DB 隧道
|
||
|
||
bridge-tools 的 4 个工具都要访问 yehwang 业务 RPC(`host.docker.internal:9632/9612/9509/9602`),
|
||
而这些服务依赖本机到 QA1 的 SSH 隧道(`172.18.0.1:3318` MySQL 等)。**隧道没起时**:
|
||
|
||
- `search_products`:`/product/list` 报 Internal Server Error → 工具回退 autocomplete,**只有商品名、没有价格/库存**;
|
||
- `search_orders` / `get_customer_info`:RPC 返回 `SQLSTATE[HY000] [2002] Connection refused`。
|
||
|
||
启动顺序:先 `yw-db-tunnel start`(`yw-db-tunnel status` 确认“已转发”),再 `docker compose up -d`。
|
||
隧道断线后工具会“半残”,排查时先看 `docker compose logs bridge-tools` 与 `testdb "select 1"`。
|
||
|
||
**隧道已配置自启 / 自愈**(dev 用户 crontab):
|
||
|
||
```
|
||
@reboot sleep 60; /home/dev/code/yehwang-ai/libredesk/scripts/ensure-tunnel.sh
|
||
*/5 * * * * /home/dev/code/yehwang-ai/libredesk/scripts/ensure-tunnel.sh
|
||
```
|
||
|
||
- [scripts/ensure-tunnel.sh](scripts/ensure-tunnel.sh) 幂等:隧道完整时静默退出,异常时 `yw-db-tunnel start` 并写 `logs/tunnel.log`;
|
||
- 依赖 cron 开机自启(已确认 enabled)和 `yw-devbox` 容器(restart=unless-stopped,已确认);
|
||
- 如需手动确认:`yw-db-tunnel status` + `testdb "select 1"`。
|
||
|
||
## 已知偏差(相对官方 quickstart)
|
||
|
||
- **DB 镜像**:官方 compose 用 `postgres:17-alpine`,本机从 docker.io / 各镜像源拉取该 tag 均失败(docker.io 长时间无进展、1panel 403、imgdb 层校验失败),
|
||
因此改用本机已缓存的 `pgvector/pgvector:pg18`(官方 `postgres` 镜像的 PG18 基础映像,`crm-new` 项目的 LibreDesk 已在用,兼容)。
|
||
PG18 的数据目录是 `/var/lib/postgresql`,compose 已按此挂载;如以后想换回 `postgres:17-alpine`,**不能直接复用数据卷**(18→17 需 dump/restore)。
|
||
- **System 用户密码强度**:libredesk 要求 10-72 位且含大小写+数字+特殊字符,纯随机 hex 会被拒绝(启动日志 `system user password is not strong`)。
|
||
|
||
## 注意事项
|
||
|
||
- `app.encryption_key` 首次启动后**不要改**,否则已保存的密钥(如收件箱密码)无法解密。
|
||
- `config.toml` 里 `disable_secure_cookies = true` 是给 http://localhost:9001 直连用的;如果只走 https,可以改回 `false` 更安全。
|
||
- 反代已按官方要求设置 `X-Client-IP $remote_addr`(限流/审计需要),见 [tls/nginx.conf](tls/nginx.conf)。
|
||
- 初始化时 compose 的 command 会执行 `--install --idempotent-install`,这是幂等的;**不要**对已有数据库手工跑 `--install`(官方文档警告它会删除已有数据)。
|
||
- 如需公网/域名访问,建议按官方文档加 Nginx 反向代理,并在 Cloudflare 场景下转发 `CF-Connecting-IP`。
|