Chatwoot · 自托管客服工单台
Chatwoot 是自托管的客户支持/工单系统,在本集群里作为共享的 support desk 运行在 app 命名空间,对外暴露在 https://support.yldm.tech(挂在 yldm.tech homelab 域名下,而非 fluxa.cash 产品域名)。它同时承载 fluxa 站点 "Contact us" 链接指向的 @fluxa_cash_bot Telegram inbox:商户私聊机器人后,消息会进入 Chatwoot 成为会话。整个服务由 web、worker、postgres 三个 Deployment 组成,注册在 yldm-services ApplicationSet 列表(serviceType app)。
部署形态
服务拆成三个 Deployment,镜像版本在 kustomization.yaml 的 images: 块统一钉死(同时作用于 web、worker 以及 web 的 db-prepare init 容器)。它没有接入 argocd-image-updater —— 这是一个支持工具,版本只在确认后手动升,不随上游每次发布自动跟。
- Name
- 命名空间
- Description
- app(kustomize 设 namespace: app、namePrefix: app-)
- Name
- 工作负载
- Description
- 三个 Deployment:web(Rails/puma)、worker(Sidekiq)、postgres(专用 DB)
- Name
- 镜像 — web / worker
- Description
- chatwoot/chatwoot:v4.14.2
- Name
- 镜像 — postgres
- Description
- pgvector/pgvector:pg16
- Name
- 副本数
- Description
- web 1、worker 1、postgres 1(三者均 replicas: 1)
- Name
- 调度
- Description
- 全部 nodeSelector workload: app
- Name
- 发布策略
- Description
- web/worker rollingUpdate(maxUnavailable 0 / maxSurge 1);postgres Recreate(单写一个 RWO 卷,禁止两个 pod 同时跑 PGDATA)
- Name
- 端口
- Description
- web 容器 3000(http);postgres 容器 5432
- Name
- 存储
- Description
- postgres 用 PVC chatwoot-postgres-data,8Gi,storageClass local-path(node-local,RWO);web/worker 无 PVC
web 的启动较慢,探针给了较宽的窗口:startupProbe 命中 /,periodSeconds 10、failureThreshold 30,即首次 Rails boot 最多 5 分钟;之后 readinessProbe / livenessProbe 同样打 /。worker 的 livenessProbe 是 pgrep -f sidekiq 进程探测。postgres 的存活/就绪探针用 pg_isready -U $POSTGRES_USER -d chatwoot。
配置与依赖
非敏感配置全部在 chatwoot-config ConfigMap,web、worker、db-prepare 都通过 envFrom 整体注入;敏感项走 ExternalSecret。kustomization 给所有 Deployment 打了 reloader.stakater.com/auto: "true",ConfigMap / Secret 变更后自动重启 pod。
ConfigMap 关键项:
| 键 | 值 | 说明 |
|---|---|---|
| RAILS_ENV / NODE_ENV | production | 运行环境 |
| INSTALLATION_ENV | kubernetes | 安装类型 |
| FRONTEND_URL | https://support.yldm.tech | 对外公开 URL,须与 Ingress host 一致 |
| DEFAULT_LOCALE | en | 默认语言 |
| ENABLE_ACCOUNT_SIGNUP | false | 内部工单台,禁止 agent 公开自助注册 |
| POSTGRES_HOST | app-chatwoot-postgres | 专用 pgvector DB 的 Service(带 namePrefix app-) |
| POSTGRES_PORT / POSTGRES_DATABASE | 5432 / chatwoot | 连接目标 |
| SIDEKIQ_CONCURRENCY | 10 | worker 并发 |
ExternalSecret chatwoot-secrets 经 ClusterSecretStore vault-backend 拉取,refreshInterval 1h,目标 secret chatwoot-secrets(creationPolicy Owner)。所有键来自 Vault 路径 yldm/production/chatwoot:
- Name
- POSTGRES_USERNAME
- Description
- remoteRef property db_user
- Name
- POSTGRES_PASSWORD
- Description
- remoteRef property db_password
- Name
- REDIS_URL
- Description
- remoteRef property redis_url,完整含密码的 Redis 连接串(复用共享 Redis,如
redis://:<pass>@redis.redis.svc.cluster.local:6379)
- Name
- SECRET_KEY_BASE
- Description
- remoteRef property secret_key_base,Rails secret;更改会使所有会话/cookie 失效
依赖关系:Chatwoot 用的是专用 pgvector Postgres,而不是共享的 postgres:16-alpine —— 因为 Chatwoot 的迁移(Captain)需要 vector 扩展,共享镜像没有。该容器以 POSTGRES_USER 为 superuser 创建,POSTGRES*DB 直接设为 chatwoot,PGDATA 在 /var/lib/postgresql/data/pgdata,fsGroup 999,从而 Chatwoot 能在自己库里跑 CREATE EXTENSION vector。web 在主容器前跑 db-prepare init 容器(rails db:chatwoot_prepare)做幂等的建库/迁移。缓存/队列后端复用集群共享 Redis(redis.redis)。SMTP 暂未配置,agent 邀请 / 通知邮件相关的 smtp*\* 属性在 external-secret 里留空,待邮件中继就绪后补上;Chatwoot 与 Telegram inbox 没有 SMTP 也能正常跑。
访问与监控
对外通过 chatwoot Service(ClusterIP,port 80 → targetPort 3000,selector component: web)+ Ingress 暴露。Ingress chatwoot 用 ingressClassName traefik,host support.yldm.tech,路径 / 前缀转到 chatwoot:80。
路由链路:external-dns 管理 yldm.tech 区,Ingress 上的两个注解(external-dns.alpha.kubernetes.io/target 指向 …cfargotunnel.com、cloudflare-proxied: "true")把 support.yldm.tech 建成指向 yldm Cloudflare tunnel 的 proxied CNAME。tunnel 把 *.yldm.tech 转给 Traefik,Traefik 按 Host 命中此 Ingress。TLS 在 Cloudflare 边缘终止,所以没有 tls 块、不走 cert-manager。yldm.tech 在 Traefik 层没有 *.yldm.tech 通配 Ingress,因此不需要 router.priority(与 fluxa.cash 域不同)。
NetworkPolicy(app 命名空间默认 deny-ingress,需要两条放行):
allow-chatwoot-postgres—— 允许带app: chatwoot标签的 web/worker pod 访问同命名空间 postgres 的 5432。allow-chatwoot-web-traefik—— 命名空间级的allow-traefik-ingress只开了 8080,而 Chatwoot web 监听 3000,所以单独放行 kube-system(Traefik)到 web pod 的 3000,否则边缘会 502。
未配置 ServiceMonitor / PrometheusRule / HPA / VPA / PDB —— 目录里没有这些清单。
注意事项
来自该服务目录 README 的运维提示:
- 首次安装(pod 健康后):打开
https://support.yldm.tech完成 install wizard 创建 super-admin,再进 Inbox → Add inbox → Telegram 粘贴@fluxa_cash_bot的 token —— Chatwoot 会注册 webhook,之后商户 DM 变成会话。 - 专用 DB 自建:专用 Postgres 在首次启动时自己创建
chatwoot数据库和(superuser)角色,无需手动建库。Vault 中secret/yldm/production/chatwoot已预填db_user、db_password、redis_url、secret_key_base。 - SMTP 待补:目前未配置,需要邮件中继时再往 Vault 加
smtp_*并把对应键加回external-secret.yaml。 - postgres 单写:发布策略是 Recreate,数据卷是 node-local 的 RWO local-path(Postgres 对 NFS 的 fsync/锁敏感,且支持库不需要跨节点迁移),切勿让两个 pod 同时跑同一 PGDATA。
返回 app 服务总览