Chatwoot 開源客服台怎麼看?開源範圍、VPS 規格、技術棧與高流量承載
Chatwoot 是一套開源 self-hosted 客服平台。重點不只在多渠道 inbox,也在它開源哪些、企業版鎖哪些、最低 VPS、Rails / Vue / PostgreSQL / Redis / Sidekiq 架構,以及前端在長歷史聊天場景下怎麼做分頁載入、去重與 scroll 補償。
作者
Seer
日期
2026-07-08
Chatwoot 的重點是把客服入口收進同一個工作台,而且可以自己部署。
如果你現在有網站 live chat、email、WhatsApp、Telegram、Line、Instagram、Facebook、SMS,客服訊息很容易散在不同地方。Chatwoot 解的是這個問題:把多渠道訊息收進同一個 inbox,讓客服、營運、管理者在同一套系統裡分派、回覆、協作、看報表。
但如果要真的拿來自架,不能只看「開源客服台」這幾個字。要看五件事:
- 它開源的是哪些部分?企業版又鎖哪些?
- 最低 VPS 要多大?
- 前後端技術棧是什麼?
- 高併發流量能不能扛?
- 它到底解決哪一類客服問題?
這篇就照這五層拆。
先講結論
| 問題 | 判斷 |
|---|---|
| Chatwoot 是不是開源? | 是。Community Edition 是 MIT 授權,主要客服功能可免費自架。 |
| 開源範圍到哪裡? | repo 可看完整程式碼,但 enterprise/ 目錄屬於企業版授權;CE 可改、可部署,EE 裡的付費功能不能當 MIT 使用。 |
| 最低 VPS 怎麼抓? | 官方最低記憶體是 4GB RAM;CPU 建議最低 4 cores,可支援到 10,000 conversations/day。實務上我會把 4 vCPU / 4GB RAM 當最低可用線。 |
| 8GB RAM 有沒有必要? | 如果有多渠道、附件、AI、報表、多人同時用,8 vCPU / 8GB RAM 更穩。官方也寫 8 cores / 8GB RAM 約支援到 20,000 conversations/day。 |
| 能不能扛高併發? | 能,但不是單機硬扛。要把 Rails web、Sidekiq worker、PostgreSQL、Redis、Object Storage 分開規劃,流量再大就水平擴 app servers。 |
| 技術棧 | 後端 Ruby on Rails、Puma、Sidekiq、PostgreSQL、Redis;前端 Vue、Vite、Pinia、Vue Router、Tailwind 相關工具。 |
| 適合誰 | 想自架客服台、集中多渠道 inbox、掌握客戶資料、替代 Intercom / Zendesk 基礎客服工作流的團隊。 |
你前面說「VPN」,我這裡按「VPS / 雲主機」理解。Chatwoot 不是 VPN 服務,它是要部署在 VPS、VM、Kubernetes 或雲端平台上的客服系統。
開源是開源哪些?
Chatwoot 有 Community Edition 和 Enterprise Edition。
官方 user guide 寫得很清楚:Community Edition 是 MIT licensed;Enterprise Edition 是 proprietary license。兩者從同一個 GitHub repo 建出來,但 enterprise/ 目錄的內容受企業版授權限制。
更直接地說:
| 範圍 | 狀態 |
|---|---|
| Community Edition | 免費、開源、MIT,可自架、可修改。 |
Repo 裡非 enterprise/ 的核心程式碼 | MIT Expat license。 |
enterprise/ 目錄 | 程式碼公開可見,但內容有 copyright / proprietary license,不等於 MIT。 |
| Enterprise Edition 付費功能 | 用授權啟用,官方列出 whitelabeling、SLA management、audit logs、agent capacity management 等。 |
| CE 未來升 EE | 官方建議若未來可能升付費功能,可以裝 Enterprise Edition,因為不用重新安裝,只是 license 啟用。 |
這種模式接近 GitLab / Mattermost / Metabase 的 commercial open-source:核心功能開源,企業治理、SLA、稽核、白標、進階管理能力放在付費層。
對一般中小團隊來說,重點是:多渠道 inbox、客服協作、help center、contacts、reports 這類客服主流程,Community Edition 已經能用。
如果你需要:
- Whitelabeling
- SLA Management
- Audit Logs
- Agent scheduling
- IP blocklisting
- 更細的企業權限與支援
那就要看 Enterprise Edition。
最低 VPS 規格要怎麼抓?
官方 self-hosted requirements 給了很明確的底線:
| 資源 | 官方資訊 | 我會怎麼抓 |
|---|---|---|
| OS | 官方支援 Ubuntu 20.04;Linux-based 系統為主 | Ubuntu LTS,避免 Windows 直上 |
| CPU | 4 cores 是 recommended minimum,支援到 10,000 conversations/day | 最低 4 vCPU 起跳 |
| RAM | 4GB RAM 是 required minimum,支援到 10,000 conversations/day | 最低 4GB;正式用建議 8GB |
| Swap | 升級時至少加 1GB swap,避免資源耗盡 | 1–2GB swap |
| PostgreSQL | 唯一支援資料庫;至少 5–10GB storage,實際依資料量和附件成長 | DB 不要跟附件混在一起估,要預留成長 |
| Redis | 用於 background task queue 和 cache;官方說可從 100MB 開始,建議 Redis 7+ | 小型可同機,大一點建議獨立或 managed Redis |
| Sidekiq | 背景工作程序;很活躍的 server 可能吃 1GB+ RAM | 正式環境把 web 和 worker 拆開 |
所以最低不是「1 vCPU / 1GB RAM 能不能跑起來」這種問題。Chatwoot 是 Rails app,加上 PostgreSQL、Redis、Sidekiq、附件、即時訊息、報表,1GB 或 2GB 很容易卡在升級、背景任務或尖峰流量。
我會這樣分級:
| 場景 | VPS 等級 | 說明 |
|---|---|---|
| 測試 / demo | 4 vCPU / 4GB RAM / 40GB SSD | 對齊官方最低可用線;適合小流量驗證。 |
| 小型正式站 | 4 vCPU / 8GB RAM / 80GB SSD | 同機跑 Rails、Sidekiq、PostgreSQL、Redis 會比較穩。 |
| 中型客服 | 8 vCPU / 8GB RAM 起 | 官方寫 8 cores / 8GB RAM 可支援到 20,000 conversations/day。 |
| 成長型部署 | app server + worker + managed PostgreSQL + Redis + S3 | 別只加大單機;要拆服務。 |
如果你要省錢,最低可以從 4 vCPU / 4GB RAM 起手。但如果這是正式客服入口,我不會把 PostgreSQL、Redis、Sidekiq、Rails 全塞在 4GB RAM 裡長期跑。它能跑,但維運餘裕小。
自架架構長什麼樣?
官方 production architecture 列出 Chatwoot 需要這幾個服務:
- Chatwoot web servers
- Chatwoot workers
- PostgreSQL Database
- Redis Database
- Email service,例如 SMTP / SendGrid / Mailgun
- Object Storage,例如 S3、Azure Storage、GCS、MinIO、DigitalOcean Spaces、Linode Objects
Docker production guide 也把 web 和 worker 拆成兩個角色:
rails -> bundle exec rails s -p 3000 -b 0.0.0.0
sidekiq -> bundle exec sidekiq -C config/sidekiq.yml
它不是只有一個 container 就結束。真正的正式架構要這樣看:
| 角色 | 負責什麼 | 高流量時怎麼擴 |
|---|---|---|
| Rails web / Puma | 管理後台、API、inbox、即時互動入口 | 增加 app server,前面放 Nginx / LB |
| Sidekiq workers | 背景任務、通知、同步、郵件、整合處理 | 增加 worker 數量或獨立 worker 主機 |
| PostgreSQL | 對話、聯絡人、設定、報表資料 | 用 managed DB、調整連線池、備份、IOPS |
| Redis | queue、cache、部分即時狀態 | 獨立 Redis / managed Redis |
| Object Storage | 附件、圖片、檔案 | 用 S3-compatible storage,不要把附件都壓在主機硬碟 |
| Email service | outbound email、通知 | 用 SendGrid / Mailgun / SMTP provider |
| Reverse proxy | HTTPS、WebSocket、流量入口 | Nginx / ALB / Cloudflare 等 |
官方 Docker 文件也提醒:container 預設只 bind localhost,要用 Nginx 或其他 proxy 對外服務。這點很重要,因為 Chatwoot 有即時訊息和 API,proxy 設定要處理 Upgrade / Connection,不能只當一般靜態網站反代。
前後端技術棧
Chatwoot 是一個 Rails + Vue 的產品,不是 Node 全端 app。
從 repo 和原始檔可以拆成這樣:
| 層 | 技術 |
|---|---|
| 後端語言 | Ruby |
| 後端框架 | Ruby on Rails 7.1 |
| Ruby 版本 | repo Gemfile 目前是 Ruby 3.4.4;官方 requirements 寫 Ruby 3.2+ |
| Web server | Puma |
| Background jobs | Sidekiq 7.x |
| Database | PostgreSQL;Docker production compose 使用 pgvector/pgvector:pg16 image |
| Cache / Queue | Redis;官方建議 Redis 7+ |
| Auth / security | Devise、rack-attack 等 Rails 生態工具 |
| 前端框架 | Vue 3 |
| Build / frontend tooling | Vite、vite_rails、pnpm |
| State / routing | Pinia、Vue Router |
| 即時能力 | Rails / ActionCable 相關前端套件 |
| 圖表 / UI | Chart.js、Tailwind typography、Radix colors、Iconify、VueUse 等 |
| 部署 | Docker、Linux VM、Kubernetes Helm、Heroku、DigitalOcean 等 |
這個技術棧的意思是:
- 如果你熟 Rails,Chatwoot 很好理解,因為它是典型 Rails monolith 加前端 app。
- 如果你只熟 Node,維運時要補 Ruby / Rails / Sidekiq / Bundler / migrations 這套知識。
- 如果你要改 UI,前端是 Vue 生態,不是 React。
- 如果你要扛流量,瓶頸不只在 web server,Sidekiq、PostgreSQL、Redis 都要看。
前端在長歷史聊天場景做了哪些優化?
Chatwoot 前端真正值得看的地方,不是單純有沒有用了某個 virtual scroll 套件,而是它怎麼處理「客服對話越累積越長」這件事。
我細看目前 develop 分支的前端程式碼後,結論是:訊息流本身沒有使用 virtual scrolling;Chatwoot 用的是分頁載入、scroll 位置補償、訊息去重、暫存訊息替換、斷線後補訊息、reply message cache 這幾層來處理長歷史聊天。
1. 有 virtual scroll,但主要用在 conversation list,不是 message stream
Chatwoot 的 package.json 有 virtua,也確實在前端使用 Virtualizer。
但目前明確看到的使用位置是:
dashboard/components/ConversationList.vue- emoji picker 相關元件
ConversationList.vue 裡用 Virtualizer 包住左側 conversation list:
<Virtualizer
ref="virtualListRef"
v-slot="{ item }"
:data="conversationList"
>
<ConversationItem :source="item" />
</Virtualizer>
這代表左側客服案件列表有做 windowing,適合大量 conversation 的 inbox。可是單一對話裡的訊息列表,MessageList.vue 是直接:
<template v-for="(message, index) in allMessages" :key="message.id">
<Message v-bind="message" />
</template>
所以不能寫成「Chatwoot 的聊天訊息流用了 virtual scroll」。比較準確的寫法是:Chatwoot 在 conversation list 使用 virtualized rendering;單一 message stream 仍是把已載入的 messages 全部渲染。
| 判斷 | 支持程度 | 依據 |
|---|---|---|
| 左側 conversation list 有 virtual scroll | 強 | ConversationList.vue import Virtualizer from virtua/vue,並用 :data="conversationList"。 |
| 單一聊天訊息流有 virtual scroll | 弱 / 不支持 | MessageList.vue 用 v-for="message in allMessages" 直接渲染,沒有看到 Virtualizer。 |
2. 長歷史聊天靠「往上捲載入舊訊息」
Dashboard 端的 MessagesView.vue 會監聽 .conversation-panel 的 scroll。當使用者捲到頂部附近,也就是 scrollTop < 100,才去抓更舊的訊息:
if (scrollTop < 100 && !this.isLoadingPrevious && shouldLoadMoreMessages) {
await this.$store.dispatch('fetchPreviousMessages', {
conversationId: this.currentChat.id,
before: this.currentChat.messages[0].id,
});
}
API 端則透過 MessageApi.getPreviousMessages({ conversationId, after, before }),把 before 和可選的 after 傳到 /conversations/:id/messages。
Store 收到 payload 後,不是重抓整個對話,而是把舊訊息 prepend 到目前 messages 前面:
chat.messages.unshift(...data);
這對長歷史聊天很重要。它把「載入全部歷史」改成「先載近期,再按需往前拉」。
| 優化 | 支持程度 | 說明 |
|---|---|---|
| 舊訊息分頁載入 | 強 | fetchPreviousMessages 使用 before: currentChat.messages[0].id。 |
| 捲到頂部才載入 | 強 | scrollTop < 100 才觸發。 |
| 舊訊息 prepend | 強 | SET_PREVIOUS_CONVERSATIONS 用 unshift(...data)。 |
| 避免重複載入到底 | 強 | payload 空時設 allMessagesLoaded = true。 |
3. prepend 舊訊息後,用 scroll height 補償避免畫面跳掉
長聊天列表最容易出現的問題是:使用者往上看舊訊息,一載入更舊的訊息,整個畫面突然跳走。
Chatwoot 在載入前記下:
this.heightBeforeLoad = this.conversationPanel.scrollHeight;
this.scrollTopBeforeLoad = this.conversationPanel.scrollTop;
載入後算高度差:
const heightDifference =
this.conversationPanel.scrollHeight - this.heightBeforeLoad;
this.conversationPanel.scrollTop =
this.scrollTopBeforeLoad + heightDifference;
這段的效果是:舊訊息加到上方後,把 scrollTop 往下補同樣高度,讓使用者原本看的訊息仍停在相近位置。
這不是 virtual scroll,但它是長歷史聊天室必備的體驗優化。
4. 新訊息與暫存訊息用 echo / pending replacement 去重
客服回覆時,前端會先建立 pending message,讓畫面立刻出現送出中的訊息。API 回來後,再把 pending message 換成正式訊息。
Dashboard store 裡的 findPendingMessageIndex 會用正式 message 的 id 或 echo_id 找暫存訊息:
m => m.id === message.id || m.id === tempMessageId
ADD_MESSAGE 找到 pending message 時會直接替換:
if (pendingMessageIndex !== -1) {
chat.messages[pendingMessageIndex] = message;
} else {
chat.messages.push(message);
}
Widget 端也有類似邏輯。它用 object map 存 messages,pushMessageToConversation 會用 message id 寫入;如果是 incoming 且找到同 content 的 in_progress message,會刪掉暫存訊息再放正式訊息。
這裡能支持的說法是:Chatwoot 有 optimistic UI,也有 pending message replacement,避免同一則訊息在送出後重複出現。
不能過度寫成「多則訊息批次合併渲染」。我沒有看到 message.created websocket 事件被 coalescing 成一個批次再 render;ActionCable 的 message.created 仍是事件來了就 dispatch addMessage。
| 說法 | 支持程度 | 判斷 |
|---|---|---|
| 有 pending message replacement | 強 | findPendingMessageIndex + ADD_MESSAGE 替換。 |
| 有基本去重 | 強 | pending / echo id、WhatsApp source id、missing messages filter。 |
| websocket 多則訊息合併成批次 render | 弱 | 沒看到明確 batching;message.created 逐則 dispatch。 |
5. WhatsApp 有 source_id 去重
在 WhatsApp channel,MessagesView.vue 會先跑:
if (this.isAWhatsAppChannel) {
return filterDuplicateSourceMessages(messages);
}
filterDuplicateSourceMessages 會用 source_id 去重,遇到重複 source id 時保留前面那則。測試也明確驗證:wa_1 多則只留 id 較小、較早進入陣列的那則。
這段屬於 channel-specific 的資料清理,不是通用效能優化。但在長歷史聊天裡,它能避免同一來源訊息重複渲染,也能減少列表雜訊。
6. 斷線重連後會補缺訊息,不只靠 websocket
長時間開著客服台,websocket 斷線是常態。Chatwoot 有 ReconnectService:
- disconnect 時記下目前 active conversation 的 last message id
- reconnect 後對目前 conversation dispatch
syncActiveConversationMessages - API 用
after: lastMessageId抓斷線期間的新訊息 - 前端 filter 掉已存在 message id
- 再依
created_at排序後寫回 store
核心邏輯是:
const missingMessages = payload.filter(
message => !messages.find(item => item.id === message.id)
);
selectedChat.messages.push(...missingMessages);
const sortedMessages = selectedChat.messages.sort((a, b) => {
return new Date(a.created_at) - new Date(b.created_at);
});
這段對長歷史場景很有用,因為它不是假設 websocket 永遠可靠,而是在重連時補齊缺口。
7. Reply message 有 cache,避免引用訊息重複打 API
MessageList.vue 裡有 fetchedReplyMessages = reactive(new Map())。當某則 message 是 reply,但被引用的原訊息不在目前已載入 messages 裡,就會用 MessageApi.getPreviousMessages 去抓附近訊息。
抓過之後會放進 Map:
if (fetchedReplyMessages.has(messageId)) {
return fetchedReplyMessages.get(messageId);
}
找不到也 cache null,避免同一個缺失 reply 反覆打 API。
這是小但實際的優化:長歷史聊天裡,reply 可能指向很久以前的訊息;Chatwoot 不會為每次 render 重複查同一個引用。
8. 未讀數與統計有節流 / debounce
ActionCable 裡 conversation.unread_count_changed 不會每次都直接打 unread counts API。它有 5 秒 throttle:
const UNREAD_COUNTS_REFETCH_THROTTLE_MS = 5000;
Conversation stats 也會依總 conversation 數調整 debounce:
if ($state.allCount > 2000) {
superLongDebouncedFetchMetaData(commit, params);
} else if ($state.allCount > 100) {
longDebouncedFetchMetaData(commit, params);
} else {
debouncedFetchMetaData(commit, params);
}
這不是單一 message list 的優化,但對客服台整體很重要:conversation 很多時,統計和未讀數更新不能每個事件都打 API。
9. Widget 端也沒有 virtual scroll,但有同樣的舊訊息載入邏輯
網站 chat widget 的 ConversationWrap.vue 也是直接依 grouped messages render:
<ChatMessage
v-for="message in groupedMessage.messages"
:key="message.id"
:message="message"
/>
它在使用者捲到頂部附近時抓舊訊息:
if (this.$el.scrollTop < 100) {
this.fetchOldConversations({ before: this.earliestMessage.id });
this.previousScrollHeight = this.$el.scrollHeight;
}
Widget store 用 object map 存訊息:
$state.conversations[message.id] = message;
這比 array append 更容易用 id 覆蓋更新,也能避免同 id 訊息重複。但 getter 會 Object.values(_state.conversations) 再 group by date,所以載入量太大時仍會有整批轉換與分組成本。
這段能支持到什麼程度?
如果要寫進文章,我會這樣下判斷:
Chatwoot 的前端沒有把單一聊天訊息流做成 virtualized message list。它的長歷史聊天優化主要靠 cursor pagination、往上捲載入舊訊息、prepend 後 scrollTop 補償、pending message replacement、channel-specific 去重、斷線重連補訊息,以及 reply message cache。這些設計讓日常客服長對話可以穩定使用,但如果同一個 conversation 已載入非常大量 messages,前端仍會把已載入的訊息完整渲染,效能上限取決於一次載入多少、訊息內容多複雜、附件多不多,以及瀏覽器 DOM 負載。
證據強度可以分成三層:
| 層級 | 可寫內容 | 支持程度 |
|---|---|---|
| 明確程式碼支持 | conversation list 使用 virtua、message stream 分頁載入、scroll 補償、pending replacement、reconnect 補訊息、reply cache、unread counts throttle | 強 |
| 合理推論 | 這些設計能改善長歷史聊天體驗,降低初始載入量,避免 prepend 跳動,減少重複 API 和重複訊息 | 中 |
| 不該寫死 | 「Chatwoot message stream 有 virtual scrolling」、「多則 websocket 訊息會批次合併 render」、「官方保證某個前端可承載訊息數」 | 弱 / 不支持 |
所以這段最好的寫法不是直接寫「高併發前端很強」,而是寫成:Chatwoot 在客服台前端做了很多務實的長對話保護,但它的 message stream 還不是 virtualized rendering;真正的大量歷史訊息承載,仍要靠後端 pagination 和前端不要一次載入太多。
高併發流量能不能扛?
能,但要先定義「高併發」是什麼。
Chatwoot 官方用 conversations/day 給硬體參考:
| 官方參考 | 可支援量 |
|---|---|
| 4 cores / 4GB RAM | up to 10,000 conversations/day |
| 8 cores / 8GB RAM | up to 20,000 conversations/day |
| 更高量 | 水平擴充 app servers |
這表示 Chatwoot 不是只能給小團隊用。它的架構有 web servers、workers、PostgreSQL、Redis,可以水平擴。
但要注意,客服系統的壓力不是單純 page view:
- 客戶開 live chat widget
- 多個 agent 同時看 inbox
- conversation 事件持續更新
- email / webhook / channel integration 進來
- attachment 上傳
- automation / notification / report 在背景跑
- AI agent 或 bot 額外打外部 API
所以高流量下要分開看:
| 壓力來源 | 主要瓶頸 | 做法 |
|---|---|---|
| 很多訪客載入 widget | Rails web / CDN / proxy | 前面放 CDN / LB,增加 web server |
| 很多訊息同時進來 | Sidekiq / Redis / DB writes | worker 獨立擴,Redis 不要太小 |
| 多客服同時操作 inbox | Rails / PostgreSQL / WebSocket | app server 水平擴,DB 連線池和索引要看 |
| 大量附件 | local disk / object storage | 用 S3-compatible storage |
| 報表查詢 | PostgreSQL | DB 規格、索引、讀寫壓力要監控 |
| AI / bot | 外部 API latency + background jobs | 把 AI 工作丟 worker,不要卡住 web request |
如果只是 4 vCPU / 4GB RAM 單機,它適合小型到中小型使用。但如果是對外大站客服入口,我會直接設計成:
Nginx / Load Balancer
-> Chatwoot Rails web x N
-> Chatwoot Sidekiq workers x N
-> PostgreSQL managed / dedicated
-> Redis managed / dedicated
-> S3-compatible object storage
-> SMTP provider
也就是說:Chatwoot 能扛,但不能期待一台小 VPS 同時扛所有事。
它能解決什麼問題?
Chatwoot 最適合解的是「客服訊息分散」和「客服流程沒有中樞」。
1. 多渠道訊息集中
它支援 live chat、email、Facebook、Instagram、Twitter / X、WhatsApp、Telegram、Line、SMS 等入口。
這讓客服不用在不同平台切來切去,同一個客戶的互動也更容易被集中整理。
2. 支援團隊協作
Chatwoot 不是只收訊息。它還有:
- Private Notes
- @mentions
- Labels
- Canned Responses
- Auto-Assignment
- Teams and Automation
- Agent Capacity Management
- Custom Views and Filters
- Business Hours
- Auto-Responders
這些功能解的是客服團隊日常問題:誰接、誰回、怎麼分類、怎麼交接、怎麼追蹤。
3. Help center 和客服 inbox 接在一起
Chatwoot 有 help center portal,可以放 FAQ、教學文章、操作指南。
這讓它不只是「等客戶來問」,也能把重複問題導到自助內容,降低客服負擔。
4. 客戶資料和互動歷史
Chatwoot 有 contact profiles、interaction history、segments、notes、custom attributes、pre-chat forms。
這讓客服不是只看一則訊息,而是能看到客戶是誰、之前問過什麼、屬於哪個分類。
5. 報表與營運管理
官方 README 列出 conversation、agent、inbox、label、team、CSAT、downloadable reports 等報表能力。
對主管來說,這代表可以看:
- 哪個渠道訊息最多
- 哪個 inbox 最忙
- 哪些 agent 回覆量高
- 客戶滿意度如何
- 哪些標籤或問題類型重複出現
什麼情境適合 Chatwoot?
我會把 Chatwoot 放在這些情境:
| 情境 | 適合度 |
|---|---|
| 想自架客服台,不想把客戶資料全放 SaaS | 高 |
| 已經有多個客服渠道,訊息分散 | 高 |
| 想找 Intercom / Zendesk 的開源替代品 | 高 |
| 有內部工程能力維運 Rails / Docker / DB | 高 |
| 只有一個簡單聯絡表單 | 低 |
| 不想碰 server、備份、升級、proxy | 低,直接用 SaaS 比較省事 |
| 需要大型企業治理、SLA、audit logs、白標 | CE 不夠,要看 EE |
Chatwoot 的價值不是「免費客服軟體」,而是你能把客服工作流和資料控制權拿回來。
自架要注意哪些維運責任?
自架 Chatwoot 不是裝完就結束。你要負責:
- HTTPS / reverse proxy
- Docker image 更新
- Rails database migration
- PostgreSQL 備份與還原
- Redis 密碼和可用性
- Sidekiq queue 堆積監控
- SMTP / channel integration 設定
- Object storage 權限和容量
- 環境變數管理
- security updates
官方 Docker 文件也提醒,升級時要跑:
docker compose pull
docker compose up -d
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
如果你的安裝很舊,官方建議不要直接跳到最新版,要逐版看 release notes 和中間版本。
這代表 Chatwoot 的門檻不在產品使用,而在維運。
我會怎麼部署
如果是小團隊試用,我會這樣起手:
一台 4 vCPU / 4GB RAM VPS
Ubuntu LTS
Docker Compose
Nginx + Let’s Encrypt
PostgreSQL + Redis 同機
S3-compatible object storage
SMTP provider
如果是正式客服入口,我會改成:
Nginx / Load Balancer
Rails web server x 2+
Sidekiq worker x 1+
Managed PostgreSQL
Managed Redis
S3-compatible object storage
SMTP provider
Monitoring + backup
如果 conversations/day 接近 10,000,我不會再用「單台 VPS 什麼都包」的想法。這時候要先拆 Sidekiq 和 database,再看 web server 要不要水平擴。
結論
Chatwoot 是一套成熟的開源客服平台。它能把 live chat、email、WhatsApp、Telegram、Line、社群訊息、help center、客服協作、報表放進同一個系統。
它開源的核心很夠用:Community Edition 是 MIT 授權,適合大多數想自架客服台的團隊。企業治理、SLA、audit logs、白標、進階支援這些功能則在 Enterprise Edition。
最低 VPS 我會抓 4 vCPU / 4GB RAM;正式環境建議 4 vCPU / 8GB RAM 起,流量再上去就拆 Rails web、Sidekiq、PostgreSQL、Redis 和 object storage。
如果你要的是「省事」,SaaS 會更快。如果你要的是「客服資料、部署、整合、流程都自己掌握」,Chatwoot 很值得看。
參考
- GitHub repo:<https://github.com/chatwoot/chatwoot>
- Chatwoot README:<https://github.com/chatwoot/chatwoot/blob/develop/README.md>
- System Requirements:<https://developers.chatwoot.com/self-hosted/deployment/requirements>
- Production Architecture:<https://developers.chatwoot.com/self-hosted/deployment/architecture>
- Docker Production Deployment:<https://developers.chatwoot.com/self-hosted/deployment/docker>
- Enterprise Edition docs:<https://developers.chatwoot.com/self-hosted/enterprise-edition>
- Enterprise Edition user guide:<https://www.chatwoot.com/hc/user-guide/articles/1677776492-enterprise-edition>
- LICENSE:<https://github.com/chatwoot/chatwoot/blob/develop/LICENSE>
Chatwoot 適合想把客服資料和部署控制權拿回來的團隊;它能扛流量,但要把 web、worker、PostgreSQL、Redis 和物件儲存分開看。
Signals
Visits
--
Waiting for Cloudflare metrics.