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.yamlimages: 块统一钉死(同时作用于 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_ENVproduction运行环境
INSTALLATION_ENVkubernetes安装类型
FRONTEND_URLhttps://support.yldm.tech对外公开 URL,须与 Ingress host 一致
DEFAULT_LOCALEen默认语言
ENABLE_ACCOUNT_SIGNUPfalse内部工单台,禁止 agent 公开自助注册
POSTGRES_HOSTapp-chatwoot-postgres专用 pgvector DB 的 Service(带 namePrefix app-)
POSTGRES_PORT / POSTGRES_DATABASE5432 / chatwoot连接目标
SIDEKIQ_CONCURRENCY10worker 并发

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.comcloudflare-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_userdb_passwordredis_urlsecret_key_base
  • SMTP 待补:目前未配置,需要邮件中继时再往 Vault 加 smtp_* 并把对应键加回 external-secret.yaml
  • postgres 单写:发布策略是 Recreate,数据卷是 node-local 的 RWO local-path(Postgres 对 NFS 的 fsync/锁敏感,且支持库不需要跨节点迁移),切勿让两个 pod 同时跑同一 PGDATA。

返回 app 服务总览

评论