SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor

วิธีติดตั้ง Rocket.Chat ด้วย Docker Compose บน VPS

คู่มือติดตั้ง Rocket.Chat บน VPS ด้วย Docker Compose พร้อมวิธีตั้งค่า MongoDB replica set ที่จำเป็น การจัดการ TLS และการสำรองข้อมูลเพื่อแก้ปัญหาข้อผิดพลาดที่พบบ่อย

สิ่งที่คุณกำลังสร้าง

ระบบแชทส่วนตัวสำหรับทีมที่คุณเป็นเจ้าของโดยสมบูรณ์: Rocket.Chat ที่ทำงานบน VPS ของคุณผ่าน Docker Compose โดยมีการทำ TLS termination และข้อความทั้งหมดจะถูกเก็บไว้ในฐานข้อมูล MongoDB ซึ่งคุณสามารถสำรองข้อมูลและย้ายได้ Rocket.Chat เป็นทางเลือกโอเพนซอร์สที่เสถียรสำหรับ Slack และ Teams รองรับการใช้งานแชนเนล, ข้อความส่วนตัว, เธรด, การแชร์ไฟล์ รวมถึงเสียงและวิดีโอ ทั้งหมดนี้อยู่บนฮาร์ดแวร์ที่คุณเช่าและควบคุมเอง อย่างไรก็ตาม นี่ไม่ใช่ตัวเลือกเดียวที่น่าเชื่อถือ หากคุณยังอยู่ในขั้นตอนการตัดสินใจ เปรียบเทียบ Mattermost, Rocket.Chat, Synapse และ Zulip จะช่วยเปรียบเทียบประเด็นสำคัญที่มักสร้างปัญหาในภายหลัง เช่น การใช้ RAM, ฐานข้อมูล, การแจ้งเตือนบนมือถือ, SSO และการอัปเกรด แอปพลิเคชันนี้เป็นคอนเทนเนอร์เดี่ยวที่สามารถเริ่มทำงานได้ภายในไม่กี่นาที สิ่งที่มักจะเกิดปัญหาจริง ๆ จะอยู่ในฐานข้อมูลที่อยู่คู่กัน ดังนั้นเนื้อหาส่วนใหญ่ของคู่มือนี้จึงเกี่ยวกับ MongoDB และโดยเฉพาะอย่างยิ่งข้อกำหนดหนึ่งที่ทำให้ทุกคนประหลาดใจในครั้งแรก: Rocket.Chat จะไม่ทำงานร่วมกับ MongoDB แบบ standalone แต่จำเป็นต้องใช้ replica set แม้ว่า "ชุด" ดังกล่าวจะมีเพียงโหนดเดียวก็ตาม

ข้อกำหนดเบื้องต้นและการคำนวณ RAM ที่ไม่มีใครบอกคุณ

จงประเมินขนาดเซิร์ฟเวอร์ตามความเป็นจริง สำหรับทีมขนาดเล็ก สเปกขั้นต่ำที่ใช้งานได้จริงคือ 2 vCPU และ RAM 4 GB กระบวนการ Node.js ของ Rocket.Chat ต้องการ RAM ประมาณ 1 ถึง 1.5 GB โดยตัวมันเอง ส่วน MongoDB นั้น WiredTiger cache จะตั้งค่าเริ่มต้นไว้ที่ค่าที่มากกว่าระหว่าง 50% ของ (RAM ทั้งหมดลบด้วย 1 GB) หรือ 0.256 GB ค่าเริ่มต้นนี้ตั้งสมมติฐานว่า mongod ได้ใช้เครื่องเพียงลำพัง โดยคำนวณจาก RAM ทั้งหมดโดยไม่คำนึงถึงสิ่งที่ Node ใช้งานอยู่แล้ว ดังนั้นบนเครื่องขนาด 4 GB จะใช้ RAM ไป 1.5 GB และบนเครื่อง 2 GB จะใช้ประมาณ 0.5 GB ซึ่งยังไม่รวม heap ของ Node, หน่วยความจำส่วนอื่นของ mongod นอกเหนือจาก cache และหน่วยความจำของระบบปฏิบัติการ บน VPS ขนาด 2 GB ทั้งสองบริการอาจทำงานได้ตอนเริ่มระบบ แต่จะเกิดปัญหาทันทีที่มี traffic จริงเข้ามา เพราะ MongoDB จะขยาย cache, Node จะขยาย heap, kernel จะขาดแคลนหน่วยความจำ และ out-of-memory killer จะสั่งปิดกระบวนการที่ใหญ่ที่สุด ซึ่งมักจะเป็น mongod ส่งผลให้ container แสดงข้อความ Killed และ Docker จะสั่ง restart ใหม่ ทำให้คุณได้เซิร์ฟเวอร์แชทที่ล่มทุกสองสามนาทีภายใต้ภาระงานที่ควรจะรับมือได้สบายๆ ขนาด 2 GB เหมาะสำหรับการทดสอบใช้งานกับคนสองคนเท่านั้น ไม่ใช่สำหรับเซิร์ฟเวอร์ของทีม เริ่มต้นที่ 4 GB และขยับเป็น 8 GB หากคุณคาดหวังผู้ใช้งานพร้อมกันจำนวนมาก การประชุมวิดีโอ หรือประวัติการอัปโหลดที่เพิ่มขึ้นเรื่อยๆ นอกจากนี้ต้องเผื่อ RAM สำหรับบริการอื่นๆ ที่จะรันบนเครื่องด้วย เช่น การติดตั้ง พื้นที่ทำงาน AFFiNE สไตล์ Notion บน VPS เดียวกัน จะเพิ่ม container อีกสี่ตัวที่ต้องแย่งชิงหน่วยความจำกัน ดังนั้น RAM สำหรับบริการเหล่านี้ต้องเพิ่มขึ้นจากเดิม ไม่ใช่ไปดึงมาจากส่วนของ Rocket.Chat

คุณต้องเตรียมความพร้อมสามประการก่อนเริ่มดำเนินการ: ชื่อโดเมนที่มี A record ชี้ไปยัง IP สาธารณะของ VPS เนื่องจากฟีเจอร์แบบ real-time และแอปมือถือของ Rocket.Chat ต้องการ hostname ที่เสถียร ไม่ใช่ IP เปล่าๆ, เปิดพอร์ต 80 และ 443 ทั้งบน firewall ของเซิร์ฟเวอร์และ network firewall ของผู้ให้บริการ ซึ่งมักจะเป็นการตั้งค่าแยกต่างหากในแผงควบคุมส่วนใหญ่ และสุดท้ายคือ Ubuntu 24.04 KVM VPS ที่ติดตั้งใหม่พร้อมสิทธิ์ root หรือ sudo หากคุณยังตัดสินใจไม่ได้ว่าเซิร์ฟเวอร์แชทเป็นบริการแรกที่ควรติดตั้งหรือไม่ คู่มือสิ่งที่ควรทำ self-hosting ในปี 2026 จะช่วยอธิบายข้อดีข้อเสียให้คุณพิจารณา

ติดตั้ง Docker engine และ Compose plugin

ให้ใช้ apt repository ของ Docker โดยตรง แทนที่จะใช้แพ็กเกจ docker.io ที่มากับ Ubuntu หรือไฟล์ไบนารี Python แบบ standalone รุ่นเก่า docker-compose สำหรับ Compose รุ่นใหม่จะเป็น Docker plugin ที่เรียกใช้งานผ่านคำสั่ง docker compose โดยใช้เว้นวรรคแทนการใช้ขีดกลาง ส่วน docker-compose v1 รุ่นเก่าได้สิ้นสุดระยะเวลาสนับสนุนแล้ว และจัดการเรื่อง healthcheck รวมถึงไวยากรณ์ของ dependency ที่ระบุไว้ด้านล่างไม่ถูกต้อง

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

ตรวจสอบให้แน่ใจว่าติดตั้งทั้งสองส่วนเรียบร้อยแล้ว:

sudo docker version
sudo docker compose version

การใช้ docker compose version เพื่อแสดงบรรทัดเวอร์ชันคือวิธีตรวจสอบที่สำคัญ รุ่นปัจจุบันจะแสดงผลเป็น Docker Compose version v5.x (v5.6.0 ซึ่งปล่อยออกมาเมื่อวันที่ 2 ตุลาคม 2026 เป็นเวอร์ชันล่าสุด ณ วันที่ 2026-10-10) การติดตั้งรุ่นเก่าอาจยังแสดงผลเป็น v2.x ซึ่ง Docker รองรับทั้งสองแบบ Docker อธิบายว่า Compose v5 มีฟังก์ชันการทำงานเหมือนกับ v2 ทุกประการ โดยเปลี่ยนเลขเวอร์ชันเป็น v5 เพื่อป้องกันความสับสนกับรูปแบบไฟล์ compose v2 และ v3 แบบดั้งเดิม ดังนั้นจึงสามารถใช้เวอร์ชันใดก็ได้สำหรับคู่มือนี้ หากเกิดข้อผิดพลาด docker: 'compose' is not a docker command แสดงว่า plugin ไม่ได้ถูกติดตั้ง และคุณจะพบปัญหาที่ซับซ้อนในภายหลัง ดังนั้นควรแก้ไขให้เรียบร้อยตั้งแต่ขั้นตอนนี้

ไฟล์ compose: MongoDB ในรูปแบบ replica set แบบโหนดเดียว

นี่คือส่วนที่คนมักทำผิดพลาด ดังนั้นโปรดอ่านอย่างละเอียด Rocket.Chat ใช้ change streams ของ MongoDB เพื่อส่งข้อความใหม่ไปยังไคลเอนต์ที่เชื่อมต่ออยู่แบบเรียลไทม์ ซึ่ง change streams จะใช้งานได้เฉพาะบน replica set เท่านั้น หากคุณชี้ Rocket.Chat ไปยัง mongod แบบ standalone ทั่วไป มันจะเชื่อมต่อได้ แต่จะล้มเหลวเมื่อเปิด change stream และวนลูป restart ไปเรื่อยๆ วิธีแก้ไขนั้นไม่ซับซ้อน: คุณเพียงแค่รันคอนเทนเนอร์ MongoDB ปกติ แต่ต้องเริ่มด้วย --replSet จากนั้นจึงทำการตั้งค่า replica set ที่มีสมาชิกเพียงหนึ่งตัว

สร้างไดเรกทอรีสำหรับทำงานและไฟล์ compose.yml:

services:
  mongodb:
    image: mongo:8.0
    restart: always
    command: ["mongod", "--replSet", "rs0", "--bind_ip_all", "--oplogSize", "128"]
    volumes:
      - mongodb_data:/data/db
      - mongodb_config:/data/configdb
    healthcheck:
      test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 10s
      retries: 12

  rocketchat:
    image: registry.rocket.chat/rocketchat/rocket.chat:8.5.1
    restart: always
    depends_on:
      mongodb:
        condition: service_healthy
    environment:
      MONGO_URL: "mongodb://mongodb:27017/rocketchat?replicaSet=rs0"
      MONGO_OPLOG_URL: "mongodb://mongodb:27017/local?replicaSet=rs0"
      ROOT_URL: "https://chat.example.com"
      PORT: "3000"
    ports:
      - "127.0.0.1:3000:3000"

volumes:
  mongodb_data:
  mongodb_config:

ตัวเลือกบางอย่างในที่นี้ถูกกำหนดไว้อย่างตั้งใจ พอร์ตของ Rocket.Chat ถูกเปิดเผยไว้ที่ 127.0.0.1:3000 ไม่ใช่ 0.0.0.0 เนื่องจากตัวแอปเองไม่มี TLS ดังนั้นควรให้เฉพาะ reverse proxy ที่อยู่บนเครื่องเดียวกันเท่านั้นที่เข้าถึงได้ การผูกพอร์ตไว้กับทุกอินเทอร์เฟซจะทำให้หน้าล็อกอินที่เป็น plaintext ปรากฏบนอินเทอร์เน็ตสาธารณะโดยตรง ส่วน MongoDB ไม่ได้ถูกเปิดเผยไปยังโฮสต์เลย มันสามารถเข้าถึงได้ผ่านเครือข่ายภายในของ Compose ภายใต้ชื่อ mongodb เท่านั้น ซึ่งเป็นชื่อโฮสต์เดียวกับที่ MONGO_URL ใช้งาน MONGO_URL จะระบุ ?replicaSet=rs0 ซึ่งเป็นการตั้งชื่อชุดข้อมูลอย่างชัดเจน MongoDB แนะนำให้ตั้งค่านี้เพื่อให้การทำงานของไดรเวอร์มีความสม่ำเสมอ การไม่ระบุค่านี้ไม่ได้ทำให้เกิดปัญหาในทันที เพราะ directConnection จะใช้ค่าเริ่มต้นเป็น false ทำให้ไดรเวอร์ยังคงค้นหา replica set และส่งคำสั่งไปยัง primary ได้ ตราบใดที่ชุดข้อมูลถูกเริ่มต้นด้วยชื่อโฮสต์ที่ Rocket.Chat สามารถ resolve ได้ ซึ่งจะกล่าวถึงในส่วนถัดไป MONGO_OPLOG_URL ชี้ไปยังฐานข้อมูล local ซึ่งเป็นที่เก็บ oplog แม้ว่า Rocket.Chat รุ่นใหม่จะนิยมใช้ change streams มากกว่า แต่การตั้งค่านี้ก็ไม่มีผลเสียและช่วยให้โค้ดรุ่นเก่าทำงานได้ตามปกติ depends_on ใช้ condition: service_healthy ดังนั้น Compose จะรอจนกว่า MongoDB จะตอบสนองต่อ ping ก่อนที่จะเริ่ม Rocket.Chat ซึ่งนั่นคือหน้าที่ของ healthcheck

กำหนดเวอร์ชันของอิมเมจให้ชัดเจน ทั้ง mongo:8.0 และรุ่นของ Rocket.Chat เช่น 8.5.1 ในที่นี้ และห้ามใช้ :latest เพราะจะทำให้การรัน docker pull แบบอัตโนมัติกลายเป็นการอัปเกรดโดยไม่ตั้งใจซึ่งอาจย้อนกลับไม่ได้ ก่อนกำหนดเวอร์ชัน โปรดตรวจสอบรุ่น Rocket.Chat ที่เสถียรในปัจจุบันและเวอร์ชันของ MongoDB ที่รองรับ Rocket.Chat มีการเผยแพร่เอกสารข้อมูลที่อ่านได้ด้วยเครื่องในแต่ละรุ่น: mongo:8.0 คือ engine เดียวที่รองรับสำหรับ compatibleMongoVersions: ["8.0"] ในรุ่น 8.5.1 โดยใช้ curl -s https://releases.rocket.chat/8.5.1/info | jq '{compatibleMongoVersions, lts}' พร้อมกับแฟล็ก lts ที่ระบุว่ารุ่นนั้นเป็นรุ่น long-term-support ที่ควรค่าแก่การล็อกเวอร์ชันสำหรับเซิร์ฟเวอร์ที่คุณไม่ต้องการดูแลบ่อยๆ ไม่ใช่ทุกโปรเจกต์ที่จะเผยแพร่อิมเมจแบบระบุเวอร์ชัน ในกรณีนั้นให้ล็อกเวอร์ชันที่ซอร์สโค้ดแทน เช่น การ self-host openGym workout tracker หมายถึงการ checkout git tag ที่เฉพาะเจาะจงและ build จาก tag นั้น แทนที่จะติดตาม branch ที่มีการเปลี่ยนแปลงอยู่ตลอดเวลา

การเริ่มต้นใช้งาน replica set

เริ่มการทำงานของ stack:

sudo docker compose up -d

Rocket.Chat จะเริ่มทำงานผิดพลาดทันทีและ Docker จะพยายามรีสตาร์ทบริการซ้ำๆ ซึ่งเป็นเรื่องปกติเนื่องจากยังไม่มี replica set อยู่ ให้สร้างขึ้นมาหนึ่งครั้งด้วยตนเองดังนี้:

sudo docker compose exec mongodb mongosh --eval 'rs.initiate({_id: "rs0", members: [{_id: 0, host: "mongodb:27017"}]})'

ผลลัพธ์ที่ถูกต้องคือ { ok: 1 } ภายในเวลาไม่กี่วินาที โหนดเดี่ยวจะเลือกตัวเองเป็น primary ให้ตรวจสอบด้วยคำสั่ง:

sudo docker compose exec mongodb mongosh --quiet --eval 'rs.status().members[0].stateStr'

คุณควรเห็น PRIMARY รายละเอียดที่สำคัญที่สุดในหน้านี้คืออาร์กิวเมนต์ host: "mongodb:27017" หากคุณรันคำสั่ง rs.initiate() เปล่าๆ โดยไม่มีรายการสมาชิก MongoDB จะประกาศชื่อ replica set โดยใช้ hostname ภายในของคอนเทนเนอร์ ซึ่งเป็นแฮชสุ่มอย่างเช่น a1b2c3d4e5f6 ซึ่ง Rocket.Chat ที่เชื่อมต่อจากคอนเทนเนอร์ของตัวเองจะไม่สามารถแก้ไขชื่อ (resolve) นั้นได้ ทำให้ไดรเวอร์ของ MongoDB ล้มเหลวในการค้นหา DNS และวนลูปบันทึก log MongoServerSelectionError: getaddrinfo ENOTFOUND a1b2c3d4e5f6 ตลอดไป ให้เริ่มต้นใช้งานด้วยชื่อบริการที่ชัดเจนซึ่งตรงกับ MONGO_URL ของคุณเสมอ

การบูตครั้งแรก: เฝ้าดูการเริ่มทำงาน

เมื่อชุดข้อมูลเป็น primary แล้ว การรีสตาร์ท Rocket.Chat ครั้งถัดไปจะเชื่อมต่อได้อย่างราบรื่นและเริ่มการย้ายข้อมูล (migration) สำหรับการใช้งานครั้งแรก ให้ติดตาม log ดังนี้:

sudo docker compose logs -f rocketchat

บรรทัดที่คุณต้องรอคือแบนเนอร์การเริ่มทำงาน:

+--------------------------------------------+
        SERVER RUNNING
   Rocket.Chat Version: 8.5.1
        NodeJS Version: 22.22.3 - x64
+--------------------------------------------+

การบูตครั้งแรกจะใช้เวลานานเนื่องจากแอปพลิเคชันต้องดำเนินการย้ายข้อมูลในฐานข้อมูลและสร้างดัชนี ดังนั้นควรให้เวลาระบบสัก 1 หรือ 2 นาที ก่อนที่จะกังวล หาก log แสดงข้อความ MongoServerSelectionError: Server selection timed out after 30000 ms ซ้ำๆ พร้อมรายละเอียด topology ประเภท ReplicaSetNoPrimary แสดงว่า replica set ยังไม่ได้ถูกเริ่มต้น หากแสดงข้อความ getaddrinfo ENOTFOUND ซ้ำๆ พร้อมค่า hash แบบสุ่ม แสดงว่ามีการเริ่มต้นด้วยโฮสต์ที่ไม่ถูกต้อง ในกรณีใดกรณีหนึ่ง ให้ย้อนกลับไปทำขั้นตอนก่อนหน้า เมื่อคุณเห็นข้อความ SERVER RUNNING แสดงว่า Rocket.Chat กำลังฟังคำขออยู่ที่ 127.0.0.1:3000 และถึงเวลาที่จะต้องกำหนด hostname จริงและตั้งค่า TLS ไว้ด้านหน้าบริการแล้ว

การใช้งานผ่าน TLS

ห้ามเปิดใช้งาน Rocket.Chat ผ่าน HTTP แบบปกติโดยเด็ดขาด การล็อกอินผ่าน http:// เพียงครั้งเดียวจะทำให้รหัสผ่านผู้ดูแลระบบของคุณถูกส่งต่อไปยังผู้ที่ดักจับข้อมูลระหว่างทางได้ ให้ทำ TLS termination ที่ reverse proxy บนเครื่องเดียวกันแล้วส่งต่อคำขอไปยัง 127.0.0.1:3000 สิ่งที่ต้องคำนึงถึงมี 2 ประการ: proxy ต้องส่งต่อ WebSocket upgrade headers เนื่องจาก Rocket.Chat เป็นแอปพลิเคชันแบบเรียลไทม์ซึ่งจะทำงานไม่ได้หากไม่มีส่วนนี้ และ ROOT_URL ของคอนเทนเนอร์จะต้องตรงกับที่อยู่ HTTPS สาธารณะที่ผู้ใช้พิมพ์เข้าใช้งานอย่างถูกต้อง

เริ่มต้นด้วย nginx server block แบบ HTTP ปกติที่ทำหน้าที่ proxy ไปยังแอปและส่งต่อ upgrade headers บันทึกไฟล์เป็น /etc/nginx/sites-available/rocketchat, สร้าง symlink ไปยัง sites-enabled แล้วโหลดการตั้งค่าใหม่:

server {
    listen 80;
    server_name chat.example.com;

    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

ให้เปิดใช้งานที่พอร์ต 80 ไปก่อน เนื่องจาก block ที่มี listen 443 ssl; แต่ไม่มีใบรับรองจะไม่ผ่านการตรวจสอบของ sudo nginx -t ให้โหลด nginx ใหม่ (sudo nginx -t && sudo systemctl reload nginx) จากนั้นจึงออกใบรับรอง วิธีที่สะดวกที่สุดบน Ubuntu คือ การใช้ใบรับรอง TLS จาก Let's Encrypt ด้วย Certbot และ nginx: certbot --nginx จะแก้ไข block ด้านบนให้โดยอัตโนมัติ โดยเพิ่ม listen 443 ssl;, บรรทัด ssl_certificate และการเปลี่ยนเส้นทางจาก 80 ไป 443 ให้อัตโนมัติ รวมถึงตั้งเวลาการต่ออายุใบรับรองให้คุณด้วย หากคุณใช้งานหลายคอนเทนเนอร์ผ่าน proxy เดียวกัน Traefik พร้อม TLS อัตโนมัติสำหรับแอป Docker หลายตัว จะเป็นทางเลือกที่เป็นระเบียบกว่า โดยให้เพิ่ม router และ service labels ลงในบริการ rocketchat แล้ว Traefik จะทำการร้องขอและต่ออายุใบรับรองให้คุณโดยไม่ต้องเขียน nginx block เลย ไม่ว่าจะใช้วิธีใด ให้ตั้งค่า ROOT_URL เป็น https://chat.example.com ใน compose.yml แล้วรัน sudo docker compose up -d อีกครั้งเพื่อให้คอนเทนเนอร์รับการเปลี่ยนแปลงดังกล่าว หากคุณต้องการให้เข้าถึงเซิร์ฟเวอร์ได้เฉพาะจากภายในเครือข่ายของคุณเองแทนที่จะเป็นอินเทอร์เน็ตสาธารณะ ให้วางระบบไว้หลัง WireGuard VPN ที่โฮสต์เองบน VPS และผูก proxy เข้ากับที่อยู่ของ tunnel แทน

วิซาร์ดการตั้งค่าสำหรับการใช้งานครั้งแรก

เปิดเบราว์เซอร์ไปที่ https://chat.example.com แล้ว Rocket.Chat จะนำคุณเข้าสู่ขั้นตอนวิซาร์ดสั้นๆ เริ่มจาก บัญชีผู้ดูแลระบบ (admin account) ซึ่งประกอบด้วยชื่อจริง, ชื่อผู้ใช้, อีเมล และรหัสผ่านที่คาดเดายาก นี่เป็นบัญชีเดียวที่มีอยู่ในระบบ ดังนั้นห้ามทำข้อมูลส่วนนี้หาย ต่อมาคือ ข้อมูลองค์กรและเซิร์ฟเวอร์ (organisation and server info) ได้แก่ ชื่อองค์กร, ประเภทอุตสาหกรรม, ขนาดองค์กร, ชื่อไซต์ และภาษาเริ่มต้น ข้อมูลส่วนนี้เป็นเพียงรายละเอียดทั่วไป ให้กรอกให้ครบแล้วดำเนินการต่อ จากนั้นจะเป็นตัวเลือกที่สำคัญจริง ๆ คือ การลงทะเบียนพื้นที่ทำงาน (register this workspace) กับ Rocket.Chat Cloud หรือเลือกใช้แบบ standalone (แบบแยกส่วน)

การลงทะเบียนจะช่วยให้สามารถใช้งานการแจ้งเตือนแบบ push ผ่านเกตเวย์ของ Rocket.Chat และเข้าถึง marketplace ของส่วนเสริมได้ โดยแลกกับการที่ระบบต้องเชื่อมต่อกับ control-plane ของ Rocket.Chat Cloud นอกจากนี้ การส่งการแจ้งเตือนผ่านเกตเวย์จะถูกนับรวมในโควตาการใช้งานรายเดือนของพื้นที่ทำงานของคุณด้วย ส่วนโหมด standalone จะทำให้เซิร์ฟเวอร์มีความเป็นส่วนตัวอย่างสมบูรณ์และไม่มีการพึ่งพาภายนอก แต่แอปอย่างเป็นทางการบน iOS และ Android จะไม่ได้รับการแจ้งเตือนแบบ push เนื่องจากเอกสารของ Rocket.Chat ระบุว่าแอปเหล่านั้นทำงานร่วมกับเกตเวย์บนคลาวด์เท่านั้น และเกตเวย์จะไม่ทำงานบนพื้นที่ทำงานที่ไม่ได้ลงทะเบียน วิธีแก้ไขคือการสร้างแอปมือถือในนามของคุณเอง (white-labeled build): ให้ปิดการใช้งานเกตเวย์ในการตั้งค่า Push, ใส่ใบรับรอง APNs และข้อมูลรับรอง Firebase Cloud Messaging ของคุณเอง จากนั้นให้ผู้ใช้ติดตั้งแอปที่คุณสร้างขึ้นแทนแอปอย่างเป็นทางการ เลือกโหมด standalone หากความเป็นส่วนตัวคือเป้าหมายหลักและผู้ใช้ของคุณใช้งานผ่านเว็บแอปเป็นหลัก หรือหากคุณพร้อมที่จะดูแลการเผยแพร่แอปมือถือของคุณเอง เลือกการลงทะเบียนหากการแจ้งเตือนแบบ push บนแอปอย่างเป็นทางการเป็นสิ่งที่จำเป็น คุณสามารถเปลี่ยนการตัดสินใจได้ในภายหลังที่เมนู Admin

จำกัดสิทธิ์การเข้าถึงก่อนเปิดให้ผู้อื่นใช้งาน

Rocket.Chat มาพร้อมกับการเปิดให้ลงทะเบียนได้ทันที โดยค่าเริ่มต้นของ Registration Form จะถูกตั้งไว้ที่ Public ดังนั้นใครก็ตามที่พบ URL ของคุณจะสามารถสร้างบัญชีได้ หากคุณใช้ hostname สาธารณะ นี่ถือเป็นการเปิดช่องโหว่ ให้ไปที่ Admin → Settings → Accounts → Registration แล้วตั้งค่า Registration Form เป็น Disabled เพื่อให้คุณสร้างบัญชีด้วยตนเองหรือผ่านลิงก์คำเชิญ หรือตั้งเป็น Secret URL ในระหว่างที่อยู่ในหน้านี้ ให้ปิด Allow Anonymous Read และ Allow Anonymous Write เว้นแต่คุณต้องการให้มีช่องทางสาธารณะที่อ่านได้อย่างเดียว หากการสร้างบัญชีทุกบัญชีด้วยตนเองเป็นเรื่องยุ่งยากและนี่ไม่ใช่บริการเดียวที่ทีมของคุณใช้งาน ให้เชื่อมต่อระบบล็อกอิน OAuth ของ Rocket.Chat เข้ากับ เซิร์ฟเวอร์ Authentik SSO ที่คุณโฮสต์เอง เพื่อให้การจัดการผู้เข้าและผู้ใช้งานที่ลาออกทำได้จากจุดเดียว แทนที่จะต้องทำแยกทีละแอป

ตัดสินใจด้วยว่าจะจัดเก็บไฟล์ที่อัปโหลดไว้ที่ใด ค่าเริ่มต้นของ File Upload คือ GridFS ซึ่งจะจัดเก็บรูปภาพและไฟล์แนบทั้งหมดไว้ภายใน MongoDB โดยตรง วิธีนี้ทำได้ง่าย แต่หมายความว่าฐานข้อมูลของคุณและทุก mongodump ที่คุณทำสำรองไว้จะมีขนาดใหญ่ขึ้นเรื่อยๆ ตามจำนวนภาพหน้าจอที่ผู้ใช้ส่งเข้ามา คุณสามารถเปลี่ยนที่จัดเก็บไปเป็น local filesystem หรือ S3-compatible bucket ได้ที่ Admin → Settings → File Upload พร้อมทั้งกำหนดขนาดไฟล์สูงสุดที่เหมาะสม หากทีมของคุณมีการแลกเปลี่ยนคลังรูปภาพขนาดใหญ่แทนที่จะเป็นเพียงภาพหน้าจอเป็นครั้งคราว ควรย้ายไฟล์เหล่านั้นไปไว้ในเซิร์ฟเวอร์รูปภาพโดยเฉพาะแทนที่จะเก็บในฐานข้อมูลแชท และบทความ เปรียบเทียบ PhotoPrism และ Immich จะช่วยประเมินว่าแต่ละตัวใช้ RAM เท่าใดและต้องใช้คำสั่งสำรองข้อมูลอย่างไร สำหรับทีมขนาดเล็ก GridFS ถือว่าเพียงพอ แต่ต้องตระหนักว่าไฟล์สำรองข้อมูลของคุณจะมีขนาดใหญ่ขึ้นเมื่อเวลาผ่านไป

การสำรองข้อมูลด้วย mongodump

ข้อมูลทั้งหมดของคุณอยู่ใน volume mongodb_data ห้ามคัดลอก volume ออกมาในขณะที่ฐานข้อมูลกำลังทำงานอยู่ ให้ใช้ mongodump เพื่อทำ dump ข้อมูลที่สอดคล้องกัน (consistent dump) และส่งข้อมูลไปยังไฟล์บนโฮสต์โดยตรง:

sudo docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > rocketchat-$(date +%F).archive.gz

ไฟล์ archive ที่บีบอัดด้วย gzip เพียงไฟล์เดียวนี้คือพื้นที่ทำงานทั้งหมดของคุณ ซึ่งประกอบด้วยผู้ใช้, ช่องทางสนทนา, ข้อความ, การตั้งค่า และไฟล์ต่างๆ หากคุณเก็บไฟล์อัปโหลดไว้บน GridFS หากคุณย้ายไฟล์อัปโหลดไปยังระบบไฟล์หรือ S3 ให้สำรองข้อมูลส่วนนั้นแยกต่างหาก การกู้คืนข้อมูลลงบน stack ใหม่ให้เริ่มจากการตั้งค่า replica set ก่อน จากนั้นจึงใช้คำสั่ง:

sudo docker compose exec -T mongodb mongorestore --archive --gzip --drop < rocketchat-2026-07-15.archive.gz

ให้คัดลอกไฟล์ archive ออกจากเซิร์ฟเวอร์ ไปยัง object storage, เซิร์ฟเวอร์อื่น หรือที่ใดก็ตามที่หาก VPS หลักเสียหาย ข้อมูลสำรองจะไม่สูญหายไปพร้อมกัน และให้ตั้งค่าการทำ dump ผ่าน cron เป็นประจำทุกคืน ข้อมูลสำรองที่คุณไม่เคยทดสอบกู้คืนถือเป็นเพียงความหวัง ไม่ใช่การสำรองข้อมูลที่แท้จริง ควรฝึกซ้อมการกู้คืนบน VPS ชั่วคราวอย่างน้อยหนึ่งครั้งเพื่อให้มั่นใจว่าใช้งานได้จริงก่อนถึงเวลาที่จำเป็นต้องใช้

การอัปเกรด: การกำหนดแท็ก, การอ่านบันทึกประจำรุ่น และการปฏิบัติตามตารางรองรับของ MongoDB

กฎสองข้อที่ช่วยให้การอัปเกรดเป็นเรื่องปกติและไม่เกิดปัญหา ข้อแรกคือ อัปเกรด Rocket.Chat ทีละเวอร์ชันหลัก (major version) ซอฟต์แวร์จะทำการย้ายฐานข้อมูล (schema migration) เมื่อเริ่มทำงาน และเอกสารการอัปเกรดของ Rocket.Chat ระบุให้ปรับปรุงตามลำดับเวอร์ชันหลักเสมอ โดยเตือนว่าการข้ามเวอร์ชันหลักอาจทำให้เกิดปัญหาความเข้ากันได้ที่รุนแรง อย่าคาดหวังว่าซอฟต์แวร์จะหยุดคุณไว้: ไม่มีส่วนใดในเอกสารที่รับประกันว่าการข้ามจาก 6.x ไปยัง 8.x โดยตรงจะถูกปฏิเสธอย่างปลอดภัย และหากการย้ายข้อมูลล้มเหลวระหว่างทาง ระบบจะค้างสถานะล็อกไว้และจำเป็นต้องแก้ไขด้วยตนเอง ให้ปรับแท็กของอิมเมจไปยังรุ่นล่าสุดของเวอร์ชันหลักถัดไป อ่านบันทึกประจำรุ่นนั้นเพื่อดูการเปลี่ยนแปลงที่อาจส่งผลกระทบ (breaking changes) รัน docker compose up -d และเฝ้าดู log จนกว่าการย้ายข้อมูลจะเสร็จสิ้นก่อนดำเนินการต่อ ข้อสองคือ ปฏิบัติตามตารางรองรับของ MongoDB Rocket.Chat แต่ละรุ่นรองรับ MongoDB เวอร์ชันที่เฉพาะเจาะจง และ curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions จะระบุว่าเวอร์ชันใดบ้างที่รองรับ เมื่อคุณย้ายเวอร์ชัน MongoDB เช่น จาก 7.0 ไป 8.0 ให้ทำทีละเวอร์ชันหลักและตั้งค่า feature-compatibility version หลังจากแต่ละขั้นตอน ใน MongoDB 8.0 คำสั่งดังกล่าวต้องใช้ confirm: true อย่างชัดเจน มิฉะนั้นระบบจะปฏิเสธพร้อมข้อความแจ้งให้รันคำสั่งใหม่ด้วยแฟล็กยืนยัน:

sudo docker compose exec mongodb mongosh --eval 'db.adminCommand({setFeatureCompatibilityVersion: "8.0", confirm: true})'

ให้ทำ mongodump ก่อนการอัปเกรดส่วนประกอบใดๆ เสมอ นี่คือหลักประกันทั้งหมดที่คุณมี

รูปแบบความล้มเหลวและข้อความแจ้งเตือนที่เกี่ยวข้อง

Rocket.Chat เกิดการวนลูปการรีสตาร์ททันทีหลังจาก docker compose up และ docker compose logs rocketchat เต็มไปด้วย MongoServerSelectionError MongoDB กำลังทำงานอยู่แต่ไดรเวอร์ไม่สามารถเลือก primary ได้ และข้อความที่ปรากฏจะระบุข้อผิดพลาดที่คุณทำไว้ Server selection timed out after 30000 ms ที่มี topology type เป็น ReplicaSetNoPrimary หมายความว่าคุณยังไม่ได้รัน rs.initiate() ซึ่งหมายความว่าชุดข้อมูลยังไม่มีการตั้งค่าใดๆ getaddrinfo ENOTFOUND ตามด้วยแฮชแบบสุ่มหมายความว่าคุณเริ่มต้นระบบโดยไม่ได้ระบุ host: "mongodb:27017" อย่างชัดเจน ทำให้ MongoDB ประกาศชื่อโฮสต์ของคอนเทนเนอร์ที่ไม่สามารถแก้ไขได้ ให้วินิจฉัยด้วย sudo docker compose exec mongodb mongosh --eval 'rs.status()' หากแสดงข้อผิดพลาด MongoServerError: no replset config has been received ให้ทำการ initiate ชุดข้อมูลนั้น หากแสดงสมาชิกที่มี name เป็นแฮชแบบสุ่ม ให้ทำการ re-initiate ด้วยชื่อบริการแทน

หน้าเว็บ UI โหลดได้แต่การล็อกอินหมุนค้างตลอดเวลาและไม่เสร็จสิ้น ให้เปิดคอนโซลของเบราว์เซอร์แล้วคุณจะพบ WebSocket connection to 'wss://chat.example.com/websocket' failed ซึ่งมักเกิดจาก ROOT_URL ไม่ตรงกัน หรือพร็อกซีไม่ได้ส่งต่อ upgrade headers ให้ตรวจสอบว่า ROOT_URL ตรงกับที่อยู่สาธารณะที่ถูกต้องรวมถึง https:// และตรวจสอบว่าบล็อก location ใน nginx ของคุณได้ตั้งค่า Upgrade และ Connection "upgrade" ด้วย proxy_http_version 1.1 แล้ว หากมีการเปลี่ยนแปลงให้รัน docker compose up -d ใหม่อีกครั้ง

คอนเทนเนอร์หยุดทำงานซ้ำๆ และ docker compose ps แสดงว่า Restarting docker compose logs ตัดจบกลางคันและ sudo dmesg | tail แสดง Out of memory: Killed process 12345 (mongod) จาก oom-killer ซึ่งมี exit code เป็น 137 แสดงว่าเซิร์ฟเวอร์มี RAM ไม่เพียงพอ วิธีแก้ไขที่แท้จริงคือการอัปเกรด VPS ให้มีขนาดใหญ่ขึ้น โดยแนะนำขั้นต่ำที่ 4 GB ในระหว่างนี้ให้เพิ่ม swap และจำกัดแคชของ MongoDB ด้วย --wiredTigerCacheSizeGB ในไฟล์ command โดยตั้งค่าให้ต่ำกว่าค่าเริ่มต้น เช่น 1 สำหรับเครื่องขนาด 4 GB (ค่าเริ่มต้นคือ 1.5) หรือ 0.3 สำหรับเครื่องขนาด 2 GB (ค่าเริ่มต้นประมาณ 0.5) อย่างไรก็ตาม swap เป็นเพียงการชะลอการเกิด OOM ภายใต้ภาระงานจริงเท่านั้น:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

docker compose up ล้มเหลวด้วย Error response from daemon: driver failed programming external connectivity ... bind: address already in use มีบางอย่างใช้งานพอร์ต 3000 อยู่แล้ว ซึ่งมักจะเป็นคอนเทนเนอร์ Rocket.Chat ตัวเก่าที่หยุดทำงานไม่สมบูรณ์ หรือแอปพลิเคชันอื่น ให้ค้นหาด้วย sudo ss -ltnp | grep :3000 จากนั้นหยุดกระบวนการหรือคอนเทนเนอร์นั้น หรือเปลี่ยนฝั่งโฮสต์ของการแมปพอร์ตเป็น 127.0.0.1:3001:3000 แล้วอัปเดต proxy_pass ของพร็อกซีให้ตรงกัน

FAQ

Rocket.Chat จำเป็นต้องใช้ MongoDB replica set จริงหรือ

จำเป็น แม้จะเป็นเซิร์ฟเวอร์เดี่ยวที่มีฐานข้อมูลเพียงโหนดเดียวก็ตาม Rocket.Chat ส่งข้อความแบบเรียลไทม์โดยใช้ MongoDB change streams ซึ่งเป็นฟีเจอร์ที่มีเฉพาะใน replica set เท่านั้น mongod แบบ standalone ไม่สามารถเปิดใช้งานได้ คุณไม่จำเป็นต้องใช้เครื่องหลายเครื่อง ให้รัน MongoDB container หนึ่งตัวโดยเริ่มด้วย --replSet rs0 และเริ่มต้น replica set แบบสมาชิกเดียวด้วย rs.initiate() หากข้ามขั้นตอนนี้ ไดรเวอร์จะไม่พบ primary ทำให้ Rocket.Chat วนลูปการรีสตาร์ทด้วย MongoServerSelectionError: Server selection timed out และไม่สามารถบูตจนเสร็จสิ้นได้

Rocket.Chat ที่โฮสต์เองต้องใช้ RAM เท่าใด

ควรวางแผนไว้ที่ 4 GB เป็นขั้นต่ำสำหรับการใช้งานจริง และ 8 GB สำหรับทีมที่มีการใช้งานหนาแน่น กระบวนการ Node ของ Rocket.Chat ใช้ RAM ประมาณ 1 ถึง 1.5 GB และแคช WiredTiger เริ่มต้นของ MongoDB จะถูกกำหนดไว้ที่ครึ่งหนึ่งของ (RAM ทั้งหมดลบด้วย 1 GB) โดยคำนวณเสมือนว่าไม่มีโปรแกรมอื่นรันอยู่บนเครื่อง ในเครื่องที่มี RAM 2 GB แคชดังกล่าวจะทับซ้อนกับ heap ของ Node และ overhead ของ mongod เอง ส่งผลให้ out-of-memory killer สั่งยุติการทำงานของ mongod เมื่อมีโหลดจริง โดยจะแสดง Killed ใน log และ exit code 137 ดังนั้น 2 GB จึงเพียงพอสำหรับการทดสอบซอฟต์แวร์กับผู้ใช้จำนวนน้อยเท่านั้น

จะตั้งค่า Rocket.Chat ให้ใช้งานผ่าน HTTPS ได้อย่างไร

ให้รัน reverse proxy บน VPS เดียวกันเพื่อทำ TLS termination แล้วส่งต่อคำขอไปยัง 127.0.0.1:3000 จากนั้นตั้งค่า ROOT_URL ของ container ให้เป็น https:// สาธารณะของคุณ ตัว proxy ต้องส่งต่อ WebSocket upgrade headers มิฉะนั้นการล็อกอินจะค้าง การใช้ Certbot ร่วมกับ nginx เป็นวิธีที่ง่ายที่สุดสำหรับแอปเดียว ส่วน Traefik จะจัดการได้สะอาดตากว่าหากคุณรันหลาย container หลัง proxy ตัวเดียวและต้องการการจัดการใบรับรองอัตโนมัติ

จะสำรองข้อมูล Rocket.Chat ที่โฮสต์เองได้อย่างไร

ให้ทำ database dump ที่มีความสอดคล้องของข้อมูลด้วย mongodump แทนการคัดลอก volume โดยใช้คำสั่ง docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz ไฟล์ archive ดังกล่าวจะประกอบด้วยผู้ใช้, ช่องแชท, ข้อความ, การตั้งค่า และไฟล์ที่อัปโหลดหากคุณเก็บไว้ใน GridFS ให้คัดลอกไฟล์ออกจากเซิร์ฟเวอร์ ทำงานอัตโนมัติทุกคืนด้วย cron และซ้อมทำ mongorestore บนเครื่องทดสอบเพื่อให้มั่นใจว่าการกู้คืนข้อมูลใช้งานได้จริง

จะอัปเกรด Rocket.Chat โดยไม่ให้ MongoDB เสียหายได้อย่างไร

ให้อัปเกรด Rocket.Chat ทีละ major version เนื่องจากระบบจะรันการย้ายข้อมูล (migration) ในขณะบูต และเอกสารระบุว่าการข้ามรุ่นอาจทำให้เกิดปัญหาความเข้ากันได้ที่รุนแรง ดังนั้นควรอ่านบันทึกประจำรุ่น (release notes) ก่อนเปลี่ยน image tag ที่ระบุไว้เสมอ ตรวจสอบว่า MongoDB เวอร์ชันใดที่รุ่นเป้าหมายรองรับด้วย curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions และเมื่อคุณอัปเกรด MongoDB ให้ทำทีละ major version พร้อมทั้งตั้งค่า setFeatureCompatibilityVersion ด้วย confirm: true หลังจากอัปเกรดแต่ละครั้ง และต้องทำ mongodump ไว้ก่อนเสมอ