LibreDesk 本地实例(yehwang-ai)

按官方文档 docs.libredesk.io/getting-started/installation 的 Docker 方式部署的独立实例, 与本机 crm-new 项目里那套 LibreDesk 完全隔离(独立容器、独立数据卷、独立端口)。

两套环境

环境 访问地址 位置 说明
开发(本机) https://192.168.31.61:9443 本机 libredesk/ 自签证书 TLS 容器,日常开发/验证
测试(测试服) https://wangliang-crm.dev.gaia888.com 47.76.223.252:/data/dev/wangliang/libredesk 共享测试,宿主 nginx 提供 TLS

测试服实例要点(2026-10-29 迁移部署)

  • 目标机 ARM64,镜像 libredesk/libredesk:v2.9.1(多架构,自动取 arm64)。
  • 无 tls 容器:宿主 nginx 已有 wangliang-crm.dev.gaia888.com → 127.0.0.1:9000 的 server 块,TLS 由 letsencrypt 证书提供。
  • 端口:app 9000(0.0.0.0)、db 127.0.0.1:5440、redis 127.0.0.1:6390、bridge-tools 127.0.0.1:4100。
  • bridge-tools 额外接入 spug-net,RPC 全部指向 wangliang 空间:jsonrpc://wangliang-dev:9503/9505/9509/9506。
  • 数据从本机迁移(pg_dump 恢复),encryption_key 与本机一致;app.root_url 已改为测试服域名。
  • 旧 crm-ai(crmnew-*)栈已下线,数据卷 crm-new_pg-data / crm-new_redis-data / crm-new_twenty-data 保留。
  • 运维:ssh yw-dev 后 cd /data/dev/wangliang/libredesk && docker compose ps|logs|restart。
  • 测试服版 compose 见 deploy/testspace/docker-compose.yml(与本仓库 docker-compose.yml 的差异即上述几项); 实例配置变更(trusted_domains / widget 文案 / AI 问候规则)见 docs/testspace-config-changes.md。

访问(本机开发实例)

项 值
后台地址 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 导入你电脑的“受信任的根证书颁发机构”。

另一个等效办法(不动证书):ssh -L 9001:127.0.0.1:9001 dev@192.168.31.61,然后开 http://localhost:9001 (Origin 是 localhost,校验放行)。

常用操作

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/):

时间 DB 备份 当时版本
2026-10-28 15:02 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 v2.9.1-rc.1

回滚(到目前为止从没跑过迁移,回滚只是切镜像,不动数据):把 .env 的 LIBREDESK_IMAGE 改成目标版本(如 libredesk/libredesk:v2.9.0)再 docker compose up -d app。 只有当某次升级真的执行了迁移时才需要恢复 dump:

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)、依赖漏洞升级(PR #742)、AI 回复期间新消息继续接答、自动分配跳过 away 的 agent、日期筛选月份跳转、自定义属性可点击、automation 模板变量帮助等。详见 release notes。

当前业务配置(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)

<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,产物在 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 篇文章):
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 幂等:隧道完整时静默退出,异常时 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。
  • 初始化时 compose 的 command 会执行 --install --idempotent-install,这是幂等的;不要对已有数据库手工跑 --install(官方文档警告它会删除已有数据)。
  • 如需公网/域名访问,建议按官方文档加 Nginx 反向代理,并在 Cloudflare 场景下转发 CF-Connecting-IP。
S
Description
No description provided
Readme
98 KiB
Languages
JavaScript 93.6%
Shell 5.5%
Dockerfile 0.9%