用海外云服务器自建 Chatwoot 客服工单系统完整教程:网站对话框、全渠道接入与团队协作实战(2026最新版)
Meta Description: 2026 最新 Chatwoot 自建教程:海外云服务器用 Docker Compose 部署开源客服工单系统,配 PostgreSQL、Redis、Nginx 反代与 HTTPS、网站对话框、邮件与全渠道接入、Super Admin 控制台、附件云存储、备份升级…
- 前言
- 先搞清楚:Chatwoot 解决什么问题(与站内方案的分工)
- 部署前必须确认的硬性前提(官方要求逐条对照)
- 海外云服务器选型与价格对比
- 第 1 步:系统初始化与 Docker 环境准备
- 第 2 步:准备目录与 .env(关键变量逐个说清)
- 第 3 步:拉起四个容器(先看清 compose 做了什么)
- 第 4 步:验证服务是否真的活了
Meta Description: 2026 最新 Chatwoot 自建教程:海外云服务器用 Docker Compose 部署开源客服工单系统,配 PostgreSQL、Redis、Nginx 反代与 HTTPS、网站对话框、邮件与全渠道接入、Super Admin 控制台、附件云存储、备份升级与故障排查,附价格表与常见问题。
关键词:Chatwoot 搭建、自建客服系统、Chatwoot 教程、开源工单系统、Chatwoot Docker 部署、网站客服对话框、Chatwoot 反向代理配置、多渠道客服、Chatwoot 备份升级、海外云服务器
前言
自建 Chatwoot 之后,客户在网站上发的每一条消息、每一封客服邮件、每一个工单的状态,都留在你自己的海外云服务器里——聊天记录不经过任何第三方 SaaS,历史数据不会因为换套餐或欠费而消失。Chatwoot 是一款用 Ruby on Rails 编写的开源客户支持 / 对话平台,把网站对话框、邮件、WhatsApp、Telegram、Facebook、Instagram、SMS 与 API 接入统一收进一个「会话(Conversation)」列表,配上团队分配、标签、宏、自动化规则和帮助中心门户,基本就是一套自托管版的在线客服台。
它的授权也足够宽松:社区版(Community Edition)走 MIT 许可,官方 FAQ 原话是「lets you use the software without any restrictions」,允许你把衍生产品再发布、再销售;只有白标、SLA 管理、审计日志、坐席容量管理这些企业功能才属于需要按坐席付费的 enterprise 目录(自托管企业版官方起价 $19 / 坐席 / 月)。当前最新稳定版为 v4.18.0(2026-09-18 发布),官方镜像 tag 形如 latest / latest-ce / v4.18.0 / v4.18.0-ce。
这篇文章给出一份可直接复制执行的完整教程:从官方硬件要求逐条对照、服务器选型与价格表,到 Docker Compose 四个容器(rails / sidekiq / postgres / redis)的部署、Nginx 反向代理与 Let's Encrypt 证书(含官方那段容易漏掉的关键配置)、首登与 Super Admin 控制台、网站对话框与邮件渠道接入、全渠道的限制表、团队协作配置、附件存储切到 S3 / MinIO、安全加固、备份恢复与升级、故障排查,最后附 10 条常见问题。
动手前请先记住官方文档里最容易踩的三条:① 数据库初始化必须用 db:chatwoot_prepare,这一步跑 db:migrate 会直接报错;② Nginx 必须显式打开 underscores_in_headers,否则 Chatwoot 的 API 请求头会被 Nginx 悄悄丢掉下划线、接口报错;③ 内存至少 4GB 再加 1GB swap,否则升级镜像时 Rails 很容易被 OOM Killer 干掉。
🚀 需要一台海外云服务器来跑 Chatwoot?通过 5.chengzicloud.cloud 购买阿里云国际版 / 腾讯云国际版 / AWS,享专属折扣。
一、先搞清楚:Chatwoot 解决什么问题(与站内方案的分工)
Chatwoot 的定位是「外部客户的问题怎么收进来、分给谁、答到哪一步」。它的数据模型是「收件箱(Inbox)→ 会话(Conversation)→ 消息(Message)」,围绕会话还有联系人(Contact)、团队(Team)、标签(Label)、宏(Canned Response / Macro)、自动化规则(Automation Rule)与自定义属性。它不替你做客服知识以外的内容管理,也不做营销群发。
自建办公与沟通类服务时,最容易犯的错是把几个功能重叠的方案混在一起选。下表把站内已经写过的相邻方案和 Chatwoot 逐一切开:
| 站内已有方案 | 它回答的问题 | 与 Chatwoot 的分工 |
|---|---|---|
| Rocket.Chat 自建 IM | 内部同事之间怎么沟通 | 面向公司自己人;Chatwoot 面向外部客户,带工单状态与分配 |
| Discourse 社区论坛 | 公开的技术社区怎么沉淀帖子 | 公开发帖、人人可见;Chatwoot 是私密一对一会话 + 工单流转 |
| 自建邮件服务器 | 邮件系统本身怎么收发 | 负责投递管道(MTA);Chatwoot 负责邮件里的问题归谁处理 |
| Vikunja 任务管理 | 内部任务怎么推进 | 内部待办;Chatwoot 是对外工单,带客户可见的会话线程 |
| n8n 工作流自动化 | 事件怎么自动流转 | 跨系统编排;Chatwoot 自带自动化规则只处理客服场景 |
| MinIO 对象存储 | 附件与文件放在哪里 | 存附件本体;Chatwoot 存会话与客户数据,附件可外挂给它 |
| Chatwoot | 客户的问题怎么收、分、答、归档 | 本文的主角 |
两条必须说清楚的反向边界:
- 它不是内部 IM,也不是社区论坛。 Rocket.Chat 的会话是「同事之间」,Discourse 的帖子是「公开可检索」;Chatwoot 的会话主线是「某个客户通过某个渠道提出的一件具体的事」,它关心的是一条会话有没有人接、多久回复、最后关没关掉。把内部沟通搬进 Chatwoot 会把客服台搞乱,反过来把客户工单丢进内部 IM 群,就没有任何可追溯的 SLA 与统计。
- 它不是 CRM,也不是邮件营销工具。 Chatwoot 有联系人列表与自定义属性,但这些字段是为对话服务的(比如「客户所在地区」「订单号」),官方文档通篇把它描述为客服 / 数据平台,并没有销售管道、商机阶段这类字段;群发营销邮件也不该用它——官方邮件渠道的定位是「客户来信后在这里回信」。
一句话选型口径:对外的、需要流转与留痕的沟通,交给 Chatwoot;对内的同事协作,交给 Rocket.Chat 或 Vikunja。
二、部署前必须确认的硬性前提(官方要求逐条对照)
Chatwoot 官方 Requirements 页把要求写得很具体,建议先逐条对照,不要用「能跑起来」的配置直接上生产。
| 项目 | 官方要求 | 实战解读 |
|---|---|---|
| 操作系统 | 官方支持 Ubuntu 20.04;其他 Unix 环境可装但非官方支持 | Docker 部署下宿主机发行版影响很小,本文用 Ubuntu 22.04 / 24.04 档次的镜像 |
| CPU | 4 核为推荐下限,可支撑约 1 万会话 / 天;8 核约 2 万 / 天 | 再高的量官方建议横向加应用服务器 |
| 内存 | 4GB 为必需下限(对应 1 万会话 / 天);8GB 对应 2 万 / 天 | 低于 4GB 不是「慢」,而是编译资产、跑 Sidekiq 时会直接 OOM |
| Swap | 官方明确要求额外加至少 1GB swap | 目的是升级期间的峰值不要打爆内存 |
| 数据库 | 只支持 PostgreSQL,官方「暂无支持其他数据库的计划」 | 5–10GB 存储起步;本文用官方镜像自带的 PostgreSQL 16 |
| Redis | 官方推荐 7.0 及以上,容量 100MB 起步即可 | 它存后台任务队列与缓存,不是可选项 |
| Sidekiq | 单进程可达 1GB+ 内存,长期运行可能因内存泄漏继续涨 | 官方建议 Web 与 Worker 分离部署以提升扩展性 |
| Docker | 官方建议 Docker ≥ 20.10.10、Compose ≥ v2.14.1 | 新版 compose 的容器名用短横线,旧版用下划线,命令里要对齐 |
| 域名 | 需要一个独立子域,例如 chat.example.com 或 support.example.com | FRONTEND_URL 要填这个完整地址,且必须与证书域名一致 |
关于「两种官方口径」的提醒: Requirements 页写的是 4 核 / 4GB 的硬下限,而官方 DigitalOcean 一键部署指南给的是4 vCPU / 8GB RAM 起步。两者的差异不是矛盾,而是「刚好能跑」与「跑得舒服」的差别。如果你的客服量是每天几十到几百条会话,2 核 4G(加 swap)完全够用;但这个实例是全公司客服的唯一入口,一旦 OOM 重启,客户消息就是实时丢失的——所以本文推荐生产环境直接选 4 vCPU / 8GB 档。
🚀 需要海外云服务器来部署 Chatwoot?通过 5.chengzicloud.cloud 购买阿里云国际版 / 腾讯云国际版 / AWS,享专属折扣。
三、海外云服务器选型与价格对比
Chatwoot 是典型的内存敏感型应用:Rails 进程 + Sidekiq 线程池 + PostgreSQL + Redis 全塞在一台机器上时,真正吃紧的是内存,而附件与会话记录持续增长吃的是磁盘。所以选型的顺序应该是:先定内存与 CPU(决定能扛多少会话),再定磁盘(决定能留多久历史)。
下表的价格为 2026 年 10 月直读 DigitalOcean 与 AWS Lightsail 官方定价页的档位-规格映射(阿里云国际版 / 腾讯云国际版给区间,因活动浮动较大):
| 服务商 | 最低配 | 1 核 2G | 2 核 4G(Chatwoot 可跑下限) | 4 核 8G(推荐生产档) | 计费与流量 |
|---|---|---|---|---|---|
| DigitalOcean Droplet | $6/月(1 vCPU / 1 GiB / 25 GiB SSD) | $12/月(1 vCPU / 2 GiB / 50 GiB SSD) | $24/月(2 vCPU / 4 GiB / 80 GiB SSD) | $48/月(4 vCPU / 8 GiB / 160 GiB SSD) | 含 1~5 TB 流量;自 2026-01-01 起按秒计费(最低 60 秒或 $0.01) |
| AWS Lightsail | $5/月(2 vCPU\* / 0.5 GiB / 20 GiB SSD) | $7/月(2 vCPU\* / 1 GiB / 40 GiB SSD) | $24/月(2 vCPU / 4 GiB / 80 GiB SSD) | $84/月(4 vCPU / 16 GiB / 320 GiB SSD) | 固定月费含 1~6 TB 流量,超量另计 |
| 阿里云国际版 | 约 $5–$9/月起 | 约 $12–$20/月 | 约 $24–$40/月 | 按规格递增 | 按量 / 包年包月,价格常随活动浮动 |
| 腾讯云国际版 | 约 $5–$9/月起 | 约 $12–$20/月 | 约 $24–$40/月 | 按规格递增 | 轻量应用服务器常有新用户折扣 |
\* Lightsail 低档位(0.5 / 1 / 2 GB)标注的 2 vCPU 为突发型(burstable),持续高负载会受 CPU 积分限制;$24 档(2 vCPU / 4 GiB)起为固定 vCPU。AWS 另有 Compute Optimized 系列,$42/月即 2 vCPU / 4 GiB,CPU 更实在但不加内存。
声明:本文价格数据采集于 2026 年 10 月,仅为公开官网参考区间,实际以各家官网实时价格为准,金额单位均为美元(USD)。
针对 Chatwoot 的选型口径:
- 个人 / 小团队客服(每天几十条会话):2 核 4G(DO $24 / Lightsail $24)加 1~2GB swap,PostgreSQL 与 Redis 同机,够用;
- 正式生产(多人坐席、每天数百到数千条):4 vCPU / 8GB 起步(DO $48),磁盘至少 80GB,把附件切到对象存储;
- 会话量上万 / 天:官方口径是 8 核 / 8GB,并在其之上把 Sidekiq 拆到独立机器;
- 历史会话与附件要长期留存:内存不再是瓶颈,磁盘与备份才是。附件走 S3 / MinIO(站内《MinIO 对象存储搭建教程》可直接复用),数据库备份则交给站内《服务器备份与容灾恢复方案》里的套路;
- 想统一登录:Chatwoot 支持 Google OAuth 等外部认证,也可以和站内《authentik 统一身份认证中心》配合,把客服坐席的登录纳入统一 SSO。
四、第 1 步:系统初始化与 Docker 环境准备
以下命令在 Ubuntu 22.04 / 24.04 上以 root 执行。先做基础加固与 swap,再装 Docker。
apt update && apt upgrade -y
apt install -y curl wget nano ufw
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
free -h
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
装 Docker 用官方脚本(官方部署文档给的也是这一套),装完确认版本不低于文档建议值:
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
apt install -y docker-compose-plugin
docker --version
docker compose version
最后建一个独立目录。不要把 Chatwoot 放在 /root 下:后面 Rails 容器的挂载目录与 docker exec 取容器名都依赖当前目录名,放在固定路径里排障最省事。
mkdir -p /opt/chatwoot && cd /opt/chatwoot
pwd
五、第 2 步:准备目录与 .env(关键变量逐个说清)
官方部署文档的做法是直接下载模板文件,我们沿用:
cd /opt/chatwoot
wget -O .env https://raw.githubusercontent.com/chatwoot/chatwoot/develop/.env.example
wget -O docker-compose.yaml https://raw.githubusercontent.com/chatwoot/chatwoot/develop/docker-compose.production.yaml
ls -l .env docker-compose.yaml
先生成一把密钥——SECRET_KEY_BASE 一旦改变,所有登录会话与加密数据都会失效,所以它必须是固定的一串,而不是每次重启随机生成:
openssl rand -hex 64
把输出整行复制下来,然后编辑 .env。下面这张表是本教程里真正需要你动手填的变量,其余保持默认即可:
| 变量 | 建议值 / 示例 | 作用与坑点 |
|---|---|---|
FRONTEND_URL | https://chat.example.com | 必须是带 https 的完整地址,且与证书域名、Nginx server_name 三者一致,否则登录跳转与实时消息会异常 |
SECRET_KEY_BASE | 上一步 openssl rand -hex 64 的输出 | 写死并妥善保存,进备份清单 |
RAILS_ENV | production | 生产模式,别留 development |
POSTGRES_PASSWORD | 自定强密码 | 与 docker-compose.yaml 里 postgres 服务的密码必须一致,官方文档专门提醒要改两处 |
REDIS_PASSWORD | 自定强密码 | compose 里的 Redis 用 requirepass 启动,变量要对应 |
MAILER_SENDER_EMAIL | Chatwoot <[email protected]> | 客服邮件与系统通知的发件人 |
SMTP_ADDRESS / SMTP_USERNAME / SMTP_PASSWORD / SMTP_PORT | 例如 SES / SendGrid / Mailgun | 不填则从 v2.12.0 起默认走本机 Postfix 外发,见第十一节 |
ACTIVE_STORAGE_SERVICE | local(默认) | 附件默认落在容器挂载的 /storage 目录,长期使用建议切 S3 / MinIO |
ENABLE_ACCOUNT_SIGNUP | 保持默认(不开启) | 默认不允许在登录页自助注册多租户账号,开放等于把客服台变成公共注册站点 |
DEFAULT_LOCALE | zh_CN 或 en | 界面默认语言 |
LOG_LEVEL / LOG_SIZE | info / 1024 | 生产默认 info;日志留存上限以 MB 计,官方默认保留最近 1GB |
编辑完记得核对一遍 compose 里的密码:
grep -n 'POSTGRES_PASSWORD\|REDIS_PASSWORD\|FRONTEND_URL' .env
grep -n 'POSTGRES_PASSWORD\|REDIS_PASSWORD' docker-compose.yaml
六、第 3 步:拉起四个容器(先看清 compose 做了什么)
在启动前,先明确这套 compose 会起哪些服务、分别监听什么,排障时才知道该看谁:
| 服务 | 镜像 | 作用 | 端口 / 卷 |
|---|---|---|---|
rails | chatwoot/chatwoot:latest | Web 应用(前台 + 客服台 + API) | 仅绑定 127.0.0.1:3000,卷 storage_data |
sidekiq | chatwoot/chatwoot:latest | 后台任务(收信、发信、渠道同步、通知) | 无对外端口,同挂 storage_data |
postgres | pgvector/pgvector:pg16 | 唯一支持的数据库,带 pgvector 扩展 | 内部 5432,卷 postgres_data |
redis | redis:alpine | 任务队列与缓存 | 内部 6379,requirepass 保护,卷 redis_data |
三点必须注意:
- 容器默认只监听本机 127.0.0.1:3000,官方文档说得很明确——它们「不是暴露在公网」的,必须前面放 Nginx 或其他代理。不要为了图方便把
127.0.0.1:3000:3000直接改成3000:3000长期暴露,那等于把客服台裸奔在公网上。 - 两个应用容器共用同一个
storage_data卷——用local存附件时,Web 与 Worker 必须看到同一份文件,这是很多人只跑单容器后收不到附件的原因。 - 想用社区版镜像时把 tag 换成对应的
-ce版本(例如v4.18.0-ce),latest-ce对应主分支。
先初始化数据库(注意是 db:chatwoot_prepare,不是 db:migrate):
cd /opt/chatwoot
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
官方原文写得很直白:首次建库必须用 rails db:chatwoot_prepare,此时跑 rails db:migrate 会报错。这一步会自动建表并加载基础数据,跑完后正式启动:
docker compose up -d
docker compose ps
七、第 4 步:验证服务是否真的活了
容器 Up 不等于应用可用。官方给的验证方式是直接打 API 探针:
curl -I localhost:3000/api
docker compose logs --tail=50 rails
docker compose logs --tail=50 sidekiq
curl -I localhost:3000/api 返回 200 就说明 Rails 起来了(返回 502/000 说明还在启动或已经挂了)。再看一眼内存水位,这一条对 Chatwoot 特别重要:
free -h
docker stats --no-stream
如果 free 的 available 已经贴着底线、docker stats 里 chatwoot-rails-1 与 chatwoot-sidekiq-1 各自吃到 1GB 上下,说明这台机器只能算「勉强」,正式用就该上 4 核 8G 档了。
八、第 5 步:Nginx 反向代理 + Let's Encrypt HTTPS
先装 Nginx 并新建站点配置(官方也是写进 sites-enabled):
apt install -y nginx
nano /etc/nginx/sites-enabled/chat.example.com.conf
把下面这份配置抄进去,替换两个地方:server_name 与证书路径里的域名。其中 underscores_in_headers on; 是官方专门加注释强调的一行——Nginx 默认会丢弃请求头里的下划线,而 Chatwoot 的 API 依赖带下划线的请求头,漏掉这行就会莫名接口报错:
server {
server_name chat.example.com;
set $upstream 127.0.0.1:3000;
underscores_in_headers on;
location /.well-known {
alias /var/www/ssl-proof/chatwoot/.well-known;
}
location / {
proxy_pass_header Authorization;
proxy_pass http://$upstream;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_buffering off;
client_max_body_size 0;
proxy_read_timeout 36000s;
proxy_redirect off;
}
listen 80;
}
检查并重载,然后申请证书:
nginx -t
systemctl reload nginx
apt install -y certbot python3-certbot-nginx
mkdir -p /var/www/ssl-proof/chatwoot/.well-known
certbot --webroot -w /var/www/ssl-proof/chatwoot/ -d chat.example.com -i nginx
两处实战改良(官配是能跑,但可以更稳):
- 官方配置里
client_max_body_size 0;表示不限上传体积,配合后面的 Nginx 限制,等于允许任何人往你的客服台推超大文件。除非业务上真要收大附件,建议改成client_max_body_size 25m;,并同步在 Nginx 层面加一点限速; - 官方配置全局设置了
Connection "upgrade"(为了 ActionCable 实时消息)。这是官方为了「一条配置通吃」的写法,能工作但不够精细;如果你后续做多站点复用,建议只对需要长连接的位置保留 Upgrade 头。
九、第 6 步:首次登录、管理员与 Super Admin 控制台
浏览器打开 https://chat.example.com,第一个注册的用户会走初始化(onboarding)流程,并自动成为超级管理员(Super Admin)。登进去之后有两个地方值得马上熟悉:
| 入口 | 地址 | 用途 |
|---|---|---|
| 客服工作台 | /app | 会话列表、收件箱、联系人、报表、设置 |
| Super Admin 控制台 | /super_admin | 平台级配置、账户与坐席、功能开关,以及内置的 Sidekiq 面板 |
Super Admin 里的 Sidekiq 面板是官方推荐的排障入口:邮件发不出去、渠道消息同步失败、通知不触发,基本都是后台任务在报错,先看这里再看容器日志。
需要进 Rails 控制台时,Docker 部署下的官方命令是($(basename $(pwd)) 会取到目录名,所以务必在 /opt/chatwoot 里执行):
docker exec -it $(basename $(pwd))-rails-1 sh -c 'RAILS_ENV=production bundle exec rails c'
万一部署好后打开是登录页而不是初始化页面,官方 FAQ 给了修复命令,在 Rails 控制台里执行:
Redis::Alfred.set(Redis::Alfred::CHATWOOT_INSTALLATION_ONBOARDING, true)
十、接入网站对话框(含独立站与博客场景)
网站渠道是 Chatwoot 最核心的入口:一段 JS 嵌到页面里,访客点开就是一个对话框,消息直接进客服台。
操作路径: 客服台 → 设置 → 收件箱(Inboxes)→ 添加收件箱 → 选择 Website → 填名称与域名 → 复制系统给出的那段 widget 代码 → 贴进你的网站模板(通常是全站页脚前)。
粘贴后建议立刻自测三件事:① 用无痕窗口打开网站,确认对话框能弹出;② 发一条消息,确认客服台会话列表实时出现(这一条同时验证了 WebSocket 与 FRONTEND_URL);③ 断网重连一次,确认历史会话还在。
如果你的站点是 WordPress / Typecho 这类自建博客,直接把 widget 代码加到主题的页脚模板即可;站内《WordPress 博客搭建教程》与《Typecho 博客部署教程》里都有主题文件位置说明。
如果是独立站/电商站(Shopify 等),通常只需把 widget 代码放进主题的 theme.liquid(或等价的全局模板)即可全站生效;站内《Shopify 独立站配套服务器方案》讨论过这类站点的服务器配套问题,客服台正好可以和订单后台配合使用:
| 网站渠道能力 | 说明 |
|---|---|
| 主动发起会话 | 可以,且只能对已核实(verified)的联系人发起外发会话 |
| 单条消息长度上限 | 10,000 字符(所有渠道里最宽松的之一) |
| 消息类型 | 支持收发消息与活动消息(客户做了什么动作的事件流) |
| 典型坑点 | 站点是 HTTPS、widget 走 HTTP,或 FRONTEND_URL 与访问域名不一致时,对话框能开但收不到实时消息 |
十一、接入邮件渠道:发信 SMTP 与收信
邮件渠道的价值在于「客户直接发邮件给 support@ 也能变成工单」。它其实分成两件事:发信(Chatwoot 发出回复与通知)与收信(客户来信进入会话)。
1)配置发信 SMTP
从 v2.12.0 开始,只要 .env 里不设置 SMTP_ADDRESS,Chatwoot 默认走本机自建的邮件服务(Postfix)。官方给的最小安装方式:
apt install -y postfix
安装时选择 internet-site,System mail name 填你 Chatwoot 用的域名。但这里有一个云服务器上极常见的坑,官方专门写了警告:主流云厂商默认封禁 25 端口用于外发邮件,你需要提工单申请解封(AWS、GCP、Azure、DigitalOcean 都有对应文档说明)。另外官方建议补上 MX 与 PTR 记录;如果邮件被 Gmail / Outlook 判为垃圾,再补 SPF 与 DKIM。
所以更省心的做法是直接用第三方 SMTP 中继。以下是官方给出的几个典型配置(照抄变量名即可):
Amazon SES 的官方样例(<region> 换成你的区域,如 us-east-1):
SMTP_ADDRESS=email-smtp.<region>.amazonaws.com
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true
SMTP_USERNAME=<Your SMTP username>
SMTP_PASSWORD=<Your SMTP password>
SendGrid 的官方样例——注意 SMTP_USERNAME 必须写死为字面量 apikey(这不是 API Key 本身,密码才填 API Key):
SMTP_ADDRESS=smtp.sendgrid.net
SMTP_AUTHENTICATION=plain
SMTP_DOMAIN=<your verified domain>
SMTP_ENABLE_STARTTLS_AUTO=true
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=<Your Sendgrid API key>
Mailgun 与 Mandrill 同理,只是地址与域名校验方式不同:Mailgun 用 smtp.mailgun.org 加你已验证的域名,Mandrill 用 smtp.mandrillapp.com(需在 Mailchimp 里开通 transactional email)。
改完 .env 后重启应用容器,并在 Rails 控制台里核对生效值:
cd /opt/chatwoot
docker compose up -d
docker compose run --rm rails bundle exec rails runner 'puts ActionMailer::Base.smtp_settings'
2)配置收信
收信需要把你的客服地址(如 [email protected])解析到 Chatwoot,再在收件箱里选择 Email 渠道并填好收信地址。最容易被低估的一步是「不要和已有的业务邮箱抢同一个地址」:如果公司邮箱已经占用了 support@,建议给客服台单独开一个地址(如 care@),或在这台机器上按站内《自建邮件服务器教程》的思路规划转发规则。
十二、接入社交与 IM 渠道:WhatsApp / Telegram / FB / IG / SMS / API
Chatwoot 的渠道列表覆盖了 Facebook、Instagram、SMS、WhatsApp、Email、Telegram、Line、TikTok 与 API,支持收发的消息类型在不同渠道完全一致,但"主动性"和"长度"差异极大。这是选渠道前必须先看的表(数据来自官方 Channels 文档):
| 渠道 | 能否主动发起会话 | 客户停止来信后的限制 | 单条消息上限 |
|---|---|---|---|
| Website | 可以对已核实联系人发起 | 无限制 | 10,000 字符 |
| 无限制 | 无限制 | 25,000 字符 | |
| SMS | 无限制 | 无限制 | Twilio 320 / Bandwidth 160 字符 |
| WhatsApp(Cloud API) | 不能 | 最后一条来信 24 小时后只能发已审核模板消息 | 4,096 字符 |
| WhatsApp(Twilio / 360Dialog) | 不能 | 同上(Twilio 1,600 / 360Dialog 1,600 字符) | 见左 |
| Telegram | 不能 | 首条消息必须由客户发出 | 4,096 字符 |
| 不能 | 首条必须客户发起;24 小时(人工客服开启可 7 天)后不能发推广消息 | 2,000 字符 | |
| 不能 | 同 Facebook | 1,000 字符 | |
| Line | 不能 | 首条必须客户发出 | 2,000 字符 |
| API | 无限制 | 取决于坐席回复时间窗配置 | 10,000 字符 |
三条实战结论:
- WhatsApp 的 24 小时窗口是硬约束。 想做「客户半天没回就催一下」的运营动作,只能事先准备好并通过审核的模板消息,否则发不出去;这不是 Chatwoot 的限制,而是平台规则。
- Telegram / FB / IG / Line 无法主动开新会话。 它们只能用于「客户先说话之后的承接」,所以如果你指望靠客服台主动给陌生人发消息,唯一合规且不受限的路径是邮件、SMS 与 API。
- 渠道越少,排障越轻松。 每个渠道都要配独立的应用凭据(如 FB 需要
FB_APP_ID、FB_APP_SECRET、FB_VERIFY_TOKEN),这些凭据一旦轮换就要重新同步.env并重启容器。生产环境建议先上网站 + 邮件两个渠道,跑稳了再逐个加社交渠道。
十三、把客服台用起来:收件箱、标签、宏、自动化与帮助中心
渠道接通只是「能收到消息」,真正让客服台省人力的是这几组能力:
| 能力 | 作用 | 建议起点 |
|---|---|---|
| 收件箱(Inbox) | 按渠道 / 业务线隔离会话入口 | 至少拆「售前」「售后」两条 |
| 团队与分配 | 会话自动或手动指派给坐席 / 团队 | 超过 3 个坐席再开自动分配 |
| 标签(Label) | 给会话打业务标签,便于筛选与统计 | 固定一套标签(退款 / bug / 咨询) |
| 宏与快捷回复 | 高频答复一键发送,统一口径 | 先把 10 条最高频答复沉淀下来 |
| 自动化规则 | 满足条件自动打标签、指派、关单 | 从「关键词 → 打标签」这一条开始 |
| 帮助中心(Portal) | 公开的知识库门户,官方支持自定义域名 + CNAME + 独立证书 | 沉淀 FAQ,用它先把「重复问题」挡掉 |
帮助中心的官方做法是:在客服台里建 Portal 并写文章,然后在 DNS 加一条 CNAME(例如 docs 指向你的 Chatwoot 域名),再用 certbot 单独给这个域名签证书:
certbot certonly --agree-tos --nginx -d docs.example.com
然后复制一份 Nginx 配置改成新域名并重载。这样 docs.example.com 就走自己的证书对外提供帮助内容,而数据仍然留在你自己的服务器上。
这里必须说清楚一件事:帮助中心能挡住重复问题,但它不是「客户自己就能解决一切」的银弹。它的正确用法是「客服回答过的、可公开的问题写进去,下次直接甩链接」,把坐席从重复劳动里解放出来,而不是把客户丢进文档海里自生自灭。
十四、附件存储:local 还是 S3 / MinIO
Chatwoot 用 Rails 的 Active Storage 管理附件,默认是 ACTIVE_STORAGE_SERVICE=local,文件落在 Chatwoot 根目录下的 /storage(容器里对应 storage_data 卷)。官方对本地存储的态度很直接:建议换成云存储,「以确保附件的正确备份、避免数据丢失」。
| 方案 | 配置 | 优点 | 代价 |
|---|---|---|---|
local(默认) | 不需要额外配置,附件在 storage_data 卷 | 零依赖、内网快 | 必须自己备份这个卷;换机器要搬目录;磁盘满了会连累整个应用 |
| S3 兼容对象存储 | ACTIVE_STORAGE_SERVICE 切到 S3 类,并补 S3 相关变量 | 附件与服务器解耦,天然可备份、可迁移 | 需要额外的存储成本与凭据管理 |
| S3 + 直传 | 在上面基础上开启 DIRECT_UPLOADS_ENABLED=true | 大附件不经应用服务器,省内存与带宽 | 必须给对象存储配好 CORS,否则前端直传会失败 |
推荐路线:小规模先用 local,但把 storage_data 卷明确写进备份脚本;一旦坐席人数超过 3 人、或附件以图片 / 音频 / 视频为主,就切到 S3 兼容存储——自建的话直接用站内《MinIO 对象存储搭建教程》,它兼容 S3 API,Chatwoot 的官方 Requirements 文档也明确点名支持 Minio、DigitalOcean Spaces、Linode Objects 这类 S3 兼容服务。
十五、安全加固清单
Chatwoot 是对公网开放、且带客户隐私数据的服务,加固不能省。以下八条按优先级排:
- 不暴露 3000 端口。 保持 compose 默认的
127.0.0.1:3000:3000,只让 Nginx 访问;用ss -lntp确认 3000 只监听在回环地址上。 - 保持
ENABLE_ACCOUNT_SIGNUP关闭。 默认就是关闭的,不要为了让同事自助注册而打开它——那会让陌生人在你的实例上开账号。 SECRET_KEY_BASE固定并进备份。 泄露或丢失都等于事故:前者可能伪造会话,后者会让所有人掉线。- 数据库与 Redis 密码不要用模板里的占位值。 官方文档专门提醒
.env与 compose 两处都要改。 - 防火墙只开 22 / 80 / 443。 顺手加个防爆破(站内《网站安全加固指南》有完整做法)。
- 限制上传体积。 把 Nginx 的
client_max_body_size从官方的0(不限)改成业务实际需要的上限。 - HTTPS 强制开启。
FRONTEND_URL用 https,证书到期前自动续期(certbot renew --dry-run验证)。 - 坐席账号最小授权。 客服台能看到全部客户对话历史,离职即停用账号,别共用管理员。
十六、备份、恢复与升级
官方备份文档把要备份的东西列成了四类,照着做就不会漏:
| 备份对象 | 具体内容 | 官方给的做法 |
|---|---|---|
| PostgreSQL 数据库 | 会话、消息、联系人、配置 | pg_dump -U postgres -W -F t chatwoot_production > backup.tar |
| 存储 | local 模式下 Chatwoot 根目录的 storage 文件夹(附件 / 上传) | 对目录做磁盘级备份;用 S3 则交给对象存储自己的备份策略 |
| 配置 | .env 文件(含 SECRET_KEY_BASE、SMTP、渠道凭据) | 单独留一份,和数据库备份分开存放 |
| 代码定制 | 任何手改过的代码 | 官方明确不提供定制代码支持,改过就必须自己用 git 管起来 |
在 Docker 部署下,数据库备份建议直接对容器执行,导出的文件落在当前目录:
cd /opt/chatwoot
docker compose exec -T postgres pg_dump -U postgres -F t chatwoot_production > backup-$(date +%F).tar
tar czf storage-$(date +%F).tar.gz -C /var/lib/docker/volumes storage 2>/dev/null || true
cp .env .env.backup-$(date +%F)
ls -lh backup-*.tar .env.backup-*
(storage 卷的真名形如 chatwoot_storage_data,可以先 docker volume ls 确认后再打包。)官方对备份的硬性提醒是:备份必须放到另一台机器或对象存储上,留在同一块磁盘上等于没有备份。
升级流程(官方 Docker 文档版):
cd /opt/chatwoot
docker compose down
docker compose pull
docker compose up -d
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
三条注意:① 每次升级后都要再跑一次 db:chatwoot_prepare,官方的措辞是「每当你更新镜像来处理迁移时」都要跑;② 跨版本不要一步跳到 latest,官方要求「通过中间镜像 tag 逐版本升级,并阅读各版本 release notes」;③ 先备份再升级,因为数据库迁移不可逆。如果你是用 Linux VM 方式(而非 Docker)装的,官方提供了 cwctl 工具,可直接 sudo cwctl --upgrade,但它假定你没有改过代码。
十七、常见故障排查
| 症状 | 常见原因 | 处理 |
|---|---|---|
db:chatwoot_prepare 报错 | 首次建库时误用 db:migrate | 改用 db:chatwoot_prepare;确认数据库密码与容器一致 |
| Rails 反复重启 / OOM | 内存不足 4GB、没加 swap | 加 swap,升配到 4 核 8G;把 Sidekiq 与 Web 拆开 |
| 页面能开但收不到实时消息 | WebSocket 被代理断了 | 检查 Upgrade / Connection 头、FRONTEND_URL 与实际域名一致 |
| API 请求莫名失败 | Nginx 丢掉了带下划线的请求头 | 在 server 段加 underscores_in_headers on; |
| 邮件发不出 | 云厂商封 25 端口 / SMTP 变量写错 | 换第三方 SMTP 中继;在 Rails 控制台核对 ActionMailer::Base.smtp_settings |
| 渠道消息不进来 | 渠道凭据或 Webhook 失效 | 先看 Super Admin 里的 Sidekiq 面板报错,再看 docker compose logs sidekiq |
| 上传大附件失败 | Nginx 限制或直传 CORS 未配 | 调 client_max_body_size;开 DIRECT_UPLOADS_ENABLED 时必须配 CORS |
| 磁盘写满 | local 存储 + 日志无限增长 | 清理旧备份、把附件切 S3、收紧 LOG_SIZE |
一条通用排障顺序:先 docker compose ps 看谁没起来 → 再 docker compose logs --tail=100 <服务> → 再进 Super Admin 的 Sidekiq 面板看后台任务 → 最后才动数据库。
推荐方案
| 场景 | 推荐配置 | 说明 |
|---|---|---|
| 个人 / 小团队试用 | 2 核 4G + 2G swap | 网站 + 邮件两个渠道,附件先用 local |
| 正式客服台 | 4 核 8G / 80GB SSD | 多坐席、多渠道、开自动化规则,附件切 S3 / MinIO |
| 会话量上万 / 天 | 8 核 8G+,Sidekiq 独立 | 按官方口径横向扩展应用服务器 |
🚀 现在就用海外云服务器把客服台搬回自己手里:通过 5.chengzicloud.cloud 购买阿里云国际版 / 腾讯云国际版 / AWS,享专属折扣,全球节点可选、免备案快速开通。
常见问题(FAQ)
Chatwoot 社区版能用多少坐席?要付费吗?
社区版走 MIT 许可,官方 FAQ 的原话是「lets you use the software without any restrictions」,也允许构建并再销售其衍生产品,因此自托管社区版没有按坐席收费这回事。企业版(enterprise 目录)才是专有许可,白标、SLA 管理、审计日志、坐席容量管理这类功能需要按坐席订阅;官方自托管企业版起价为 $19 / 坐席 / 月,且分发或销售企业版必须持有匹配坐席数的有效订阅。
最少要多少内存才能跑起来?
官方 Requirements 页写的是「4GB 为必需下限」(对应约 1 万会话 / 天),并额外要求至少 1GB swap,理由很实在:升级镜像时内存会出现峰值。另外 Sidekiq 单进程就可能吃到 1GB+,所以 2 核 4G 属于「能跑」,4 核 8G 才属于「生产放心」。官方 DigitalOcean 一键部署指南给的也是 4 vCPU / 8GB,比 Requirements 页更保守。
可以只装一台机器,不用 Docker 吗?
可以,官方同时提供 Linux VM(脚本 / cwctl)与 Kubernetes(官方 Helm chart)两条路。但 Docker Compose 是官方文档最完整、升级路径最清楚的一条,本文也按它来写。如果你更习惯图形化管理容器,可以配合站内《Docker + Portainer 容器可视化部署指南》看容器状态与日志。
数据库为什么只能用 PostgreSQL?我能换成 MySQL 吗?
不能。官方文档明确写着「PostgreSQL is the only supported database」,并且暂无支持其他数据库的计划。这件事要在动手前就接受,否则后期迁移成本极高——如果你的数据库还想统一管理,站内《MySQL / PostgreSQL 数据库服务器搭建指南》里有两者共存的部署经验。
一定要配 SMTP 吗?不配会怎样?
从 v2.12.0 起,只要没有设置 SMTP_ADDRESS,Chatwoot 会默认走本机自建邮件服务(Postfix)。但官方同时警告,主流云厂商默认封禁 25 端口,需要提工单解封,并建议补 MX / PTR 记录,必要时再加 SPF / DKIM 提升送达率。因此在云服务器上,配一个第三方 SMTP 中继(SES / SendGrid / Mailgun)通常比自建 Postfix 更省事。
网站对话框装了但不显示、或者收不到实时消息,怎么查?
先分两件事:对话框不出现多半是 widget 代码没贴到全站模板、或站点是 HTTPS 而 widget 走了 HTTP;能弹出来但消息不实时则是 FRONTEND_URL 与实际访问域名不一致,或 Nginx 的 WebSocket 头没配好(Upgrade / Connection / proxy_http_version 1.1)。另外别忘了 underscores_in_headers on;——Nginx 默认丢下划线请求头,会让 Chatwoot 的 API 表现得很诡异。
WhatsApp 渠道为什么发不出消息?
因为平台规则:最后一条客户来信超过 24 小时后,只能发送已审核的模板消息,其他内容发不出去。这不是 Chatwoot 的 bug,官方 Channels 文档把这条限制写在明面上。Telegram、Facebook、Instagram、Line 更严格——它们不能主动创建外发会话,首条消息必须由客户发出。
附件存在哪?会随聊天记录一起丢吗?
默认 ACTIVE_STORAGE_SERVICE=local,附件落在 Chatwoot 根目录的 storage 目录(Docker 下是 storage_data 卷)。官方明确建议改用云存储以「确保附件被正确备份、避免数据丢失」。所以:用 local 就必须把该卷写进备份脚本;想更省心就切到 S3 兼容存储,自建可用 MinIO,官方 Requirements 也点名支持 Minio、DO Spaces、Linode Objects 等 S3 兼容服务。
升级会丢数据吗?该怎么升?
db:chatwoot_prepare 会执行数据库迁移,先备份再升级是硬规矩。官方 Docker 文档要求的流程是:docker compose down → docker compose pull → docker compose up -d → 再跑一次 db:chatwoot_prepare。如果版本跨度很大,官方要求通过中间镜像 tag 逐版本升级,并阅读每个版本的 release notes;同时建议固定版本号而不要长期用 latest,把升级时机掌握在自己手里。
能不能用 Chatwoot 再做一个给自己客户用的 SaaS?
官方 FAQ 的态度是:社区版 MIT 许可允许无限制使用、也允许构建和销售衍生产品,但明确不鼓励「直接与 Chatwoot 商业产品竞争」的用法(例如克隆 Chatwoot Cloud 的 SaaS、换皮转售服务)。同时,企业版的分发与销售必须持有匹配坐席数的企业订阅。给自己的公司/客户做客服台是正常用法,做同质化 SaaS 则要谨慎评估。 延伸阅读:
- Rocket.Chat 自建团队 IM 部署教程
- Discourse 自建社区论坛搭建教程
- 自建邮件服务器完整部署教程
- MinIO 对象存储服务器搭建教程
- n8n 工作流自动化服务器部署教程
- Nginx 反向代理 + SSL 证书配置完整指南
- 网站安全加固指南:端口、权限与防爆破
- 服务器备份与容灾恢复方案
本文由 5.chengzicloud.cloud 提供,点击访问首页了解更多海外云服务器部署方案和专属优惠。