SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-26

Hướng dẫn cài đặt Rocket.Chat bằng Docker Compose

Triển khai Rocket.Chat trên VPS với Docker Compose. Hướng dẫn chi tiết cách cấu hình MongoDB replica set bắt buộc, thiết lập TLS, quản lý backup và xử lý các lỗi thường gặp.

Bạn đang xây dựng cái gì

Một hệ thống chat nội bộ mà bạn hoàn toàn làm chủ: Rocket.Chat chạy trên VPS của riêng bạn bằng Docker Compose, được bảo mật bằng TLS, với mọi tin nhắn lưu trong database MongoDB mà bạn có thể backup và di chuyển. Rocket.Chat là giải pháp thay thế mã nguồn mở hoàn thiện cho Slack và Teams, hỗ trợ kênh, tin nhắn trực tiếp, luồng thảo luận, chia sẻ file, cùng tính năng thoại và video, tất cả trên phần cứng bạn thuê và kiểm soát. Tuy nhiên, đây không phải là lựa chọn duy nhất, và nếu bạn vẫn đang cân nhắc, So sánh Mattermost, Rocket.Chat, Synapse và Zulip sẽ liệt kê các yếu tố gây khó khăn về sau: RAM, database, mobile push, SSO và nâng cấp. Ứng dụng này là một container đơn lẻ có thể khởi chạy trong vài phút. Mọi vấn đề phát sinh thực tế đều nằm ở database đi kèm, vì vậy phần lớn hướng dẫn này tập trung vào MongoDB, đặc biệt là yêu cầu khiến mọi người bất ngờ lần đầu tiên: Rocket.Chat sẽ không chạy với một MongoDB đơn lẻ (standalone). Nó yêu cầu một replica set, ngay cả khi "set" đó chỉ có một node duy nhất.

Các điều kiện tiên quyết và bài toán RAM ít người nói tới

Hãy chọn cấu hình máy chủ một cách thực tế. Mức tối thiểu khả thi cho một nhóm nhỏ là 2 vCPU và 4 GB RAM. Tiến trình Node.js của Rocket.Chat tự nó đã cần khoảng 1 đến 1.5 GB, và cache WiredTiger của MongoDB mặc định sẽ chiếm khoảng một nửa lượng RAM còn lại. Trên một VPS 2 GB, cả hai có thể khởi động được nhưng sẽ xung đột ngay khi có lưu lượng truy cập thực tế: MongoDB tăng cache, Node tăng heap, kernel cạn kiệt trang bộ nhớ, và trình OOM killer sẽ tiêu diệt tiến trình lớn nhất, thường là mongod. Container in ra Killed, Docker khởi động lại nó, và bạn nhận được một chat server bị ngắt kết nối liên tục dưới mức tải mà đáng lẽ nó phải chịu được. 2 GB chỉ đủ để dùng thử với hai người; nó không phải là server cho cả nhóm. Hãy bắt đầu với 4 GB, và cấp 8 GB nếu bạn kỳ vọng có hàng chục người dùng đồng thời, gọi video, hoặc lịch sử tải lên ngày càng tăng. Hãy tính toán cả các dịch vụ khác chạy trên máy chủ: việc đặt một không gian làm việc AFFiNE kiểu Notion trên cùng VPS sẽ thêm bốn container nữa cạnh tranh cùng lượng RAM đó, vì vậy RAM cho chúng phải được cộng thêm vào chứ không phải lấy từ phần của Rocket.Chat.

Bạn cũng cần chuẩn bị ba thứ trước khi bắt đầu. Một tên miền với A record trỏ về IP công cộng của VPS, các tính năng thời gian thực và ứng dụng di động của Rocket.Chat cần một hostname ổn định, không phải IP thuần. Cổng 80 và 443 phải mở trên cả firewall của máy chủ và firewall mạng của nhà cung cấp, đây là một thiết lập điều khiển riêng biệt trên hầu hết các bảng điều khiển. Và một VPS Ubuntu 24.04 KVM mới với quyền root hoặc sudo. Nếu bạn vẫn đang cân nhắc liệu chat server có phải là dịch vụ đầu tiên phù hợp để tự host hay không, hướng dẫn về những gì đáng để tự host trong năm 2026 sẽ giúp bạn hình dung các yếu tố cần đánh đổi.

Cài đặt Docker engine và plugin Compose

Hãy sử dụng repository apt chính thức của Docker, không dùng gói docker.io có sẵn trong Ubuntu và không dùng file binary Python docker-compose cũ kỹ. Compose hiện đại là một Docker plugin mà bạn gọi bằng lệnh docker compose, dùng dấu cách thay vì dấu gạch nối. Phiên bản docker-compose v1 cũ đã ngừng hỗ trợ và xử lý sai cú pháp healthcheck cũng như dependency bên dưới.

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

Xác nhận cả hai thành phần đã có mặt:

sudo docker version
sudo docker compose version

docker compose version in ra kết quả tương tự Docker Compose version v2.x là bước kiểm tra quan trọng. Nếu lệnh báo lỗi docker: 'compose' is not a docker command, nghĩa là plugin chưa được cài đặt và bạn sẽ gặp các lỗi khó hiểu sau này, hãy sửa ngay tại đây.

File compose: MongoDB dưới dạng replica set một node

Đây là phần nhiều người làm sai, nên hãy đọc kỹ. Rocket.Chat sử dụng change streams của MongoDB để đẩy tin nhắn mới đến client theo thời gian thực, và change streams chỉ khả dụng trên replica set. Nếu bạn trỏ Rocket.Chat vào một mongod standalone thông thường, nó sẽ kết nối được, nhưng không thể mở change stream và sẽ rơi vào vòng lặp khởi động lại mãi mãi. Cách sửa không có gì phức tạp: bạn chạy một container MongoDB bình thường, nhưng khởi động nó với --replSet rồi khởi tạo một set gồm một thành viên duy nhất.

Tạo một thư mục làm việc và một 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:

Một vài lựa chọn ở đây là có chủ đích. Cổng của Rocket.Chat được publish ra 127.0.0.1:3000, không phải 0.0.0.0, bản thân ứng dụng không có TLS, nên chỉ reverse proxy trên cùng máy chủ mới được phép truy cập; nếu bind nó ra mọi interface sẽ khiến trang đăng nhập plaintext lộ diện trực tiếp trên Internet công cộng. MongoDB hoàn toàn không được publish ra host; nó chỉ có thể truy cập qua mạng nội bộ của Compose dưới tên mongodb, đây chính xác là hostname mà MONGO_URL sử dụng. MONGO_URL chứa ?replicaSet=rs0, nếu bỏ qua nó, driver sẽ coi server là standalone mặc dù nó là một replica set, và change streams vẫn sẽ lỗi. MONGO_OPLOG_URL trỏ đến database local nơi lưu trữ oplog; Rocket.Chat hiện đại ưu tiên dùng change streams, nhưng việc thiết lập nó cũng không gây hại và giúp các đường dẫn code cũ hoạt động ổn định. depends_on sử dụng condition: service_healthy, vì vậy Compose sẽ đợi cho đến khi MongoDB phản hồi một ping trước khi khởi động Rocket.Chat, đó chính là mục đích của healthcheck.

Ghim tag version cụ thể cho cả 2 image, mongo:8.0 và một bản Rocket.Chat rõ ràng như 8.5.1 ở đây, và không bao giờ dùng :latest. Cách này biến một docker pull không cần giám sát thành một lần nâng cấp ngoài ý muốn mà không thể migration. Kiểm tra bản Rocket.Chat stable hiện tại và các version MongoDB được hỗ trợ trước khi ghim. Rocket.Chat công bố một tài liệu info có định dạng máy đọc được cho từng bản release: curl -s https://releases.rocket.chat/8.5.1/info | jq '{compatibleMongoVersions, lts}' trả về compatibleMongoVersions: ["8.0"] cho 8.5.1, vì vậy mongo:8.0 là engine duy nhất được hỗ trợ, cùng với một flag lts cho biết bản release đó có phải là bản long-term support đáng ghim cho server mà bạn không muốn phải thường xuyên theo dõi hay không. Không phải project nào cũng công bố image có version. Khi đó, việc ghim version chuyển sang source: tự host trình theo dõi bài tập openGym có nghĩa là checkout một git tag cụ thể rồi build từ tag đó, thay vì theo một branch luôn thay đổi.

Khởi tạo replica set

Khởi chạy stack:

sudo docker compose up -d

Rocket.Chat sẽ crash ngay lập tức và Docker sẽ liên tục khởi động lại nó, đây là điều bình thường vì replica set chưa tồn tại. Hãy tạo nó một lần bằng tay:

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

Kết quả đúng là { ok: 1 }. Trong vài giây, node đơn lẻ sẽ tự bầu chọn làm primary; xác nhận bằng lệnh:

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

Bạn cần thấy PRIMARY. Chi tiết quan trọng nhất trên toàn bộ trang này là tham số host: "mongodb:27017". Nếu bạn chạy lệnh rs.initiate() trần mà không có danh sách thành viên, MongoDB sẽ quảng bá replica set dưới hostname nội bộ của container, một chuỗi hash ngẫu nhiên như a1b2c3d4e5f6. Rocket.Chat, khi kết nối từ container của chính nó, không thể phân giải tên đó, nên driver MongoDB bị lỗi DNS và lặp vô tận với log MongoServerSelectionError: getaddrinfo ENOTFOUND a1b2c3d4e5f6. Luôn khởi tạo với tên service tường minh khớp với MONGO_URL của bạn.

Khởi động lần đầu: theo dõi quá trình khởi chạy

Khi set đã trở thành primary, lần khởi động lại tiếp theo của Rocket.Chat sẽ kết nối ổn định và bắt đầu các migration lần đầu. Hãy theo dõi log:

sudo docker compose logs -f rocketchat

Dòng bạn cần đợi là banner khởi động:

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

Lần khởi động đầu tiên thường chậm vì ứng dụng phải chạy migration database và xây dựng index, vì vậy hãy đợi một hoặc hai phút trước khi lo lắng. Nếu log lặp lại MongoServerSelectionError: Server selection timed out after 30000 ms với mô tả topology là loại ReplicaSetNoPrimary, nghĩa là replica set chưa được khởi tạo; nếu log lặp lại getaddrinfo ENOTFOUND với một hash ngẫu nhiên, nghĩa là nó đã được khởi tạo với sai hostname. Trong cả hai trường hợp, hãy quay lại bước trước. Khi bạn thấy SERVER RUNNING, Rocket.Chat đã lắng nghe trên 127.0.0.1:3000 và đây là lúc để đặt một hostname thực và TLS phía trước nó.

Đặt phía sau TLS

Đừng bao giờ để Rocket.Chat chạy trên HTTP thuần. Chỉ cần đăng nhập qua http:// một lần là bạn đã trao mật khẩu admin cho bất kỳ ai trên đường truyền. Hãy thực hiện TLS termination tại một reverse proxy trên cùng máy chủ và chuyển tiếp đến 127.0.0.1:3000. Có hai điều quan trọng: proxy phải chuyển tiếp các header WebSocket upgrade, vì Rocket.Chat hoạt động theo thời gian thực và sẽ lỗi nếu thiếu chúng, và ROOT_URL của container phải khớp chính xác với địa chỉ HTTPS công khai mà người dùng nhập vào.

Bắt đầu với một block server nginx HTTP thuần để proxy đến ứng dụng và chuyển tiếp các header upgrade. Lưu nó thành /etc/nginx/sites-available/rocketchat, tạo symlink vào sites-enabled, và reload:

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;
    }
}

Hãy cứ để nó ở cổng 80 lúc này, một block với listen 443 ssl; mà không có chứng chỉ sẽ không vượt qua được sudo nginx -t. Reload nginx (sudo nginx -t && sudo systemctl reload nginx), sau đó cấp chứng chỉ. Cách gọn nhất trên Ubuntu là cấp chứng chỉ TLS Let's Encrypt với Certbot và nginx: certbot --nginx sẽ ghi đè block trên, thêm listen 443 ssl;, các dòng ssl_certificate, và tự động redirect từ 80 sang 443, đồng thời lên lịch gia hạn cho bạn. Nếu bạn đã chạy nhiều container sau một proxy, Traefik với TLS tự động cho nhiều ứng dụng Docker là tùy chọn gọn gàng hơn, hãy thêm các nhãn router và service vào service rocketchat và Traefik sẽ tự yêu cầu cũng như gia hạn chứng chỉ cho bạn, mà không cần bất kỳ block nginx nào. Dù chọn cách nào, hãy đặt ROOT_URL thành https://chat.example.com trong compose.yml và chạy lại sudo docker compose up -d để container nhận thay đổi. Nếu bạn muốn server chỉ có thể truy cập từ bên trong mạng nội bộ thay vì Internet công cộng, hãy đặt nó phía sau một VPN WireGuard tự host trên VPS và bind proxy vào địa chỉ tunnel.

Thiết lập lần đầu qua trình hướng dẫn

Truy cập https://chat.example.com và Rocket.Chat sẽ dẫn bạn qua một trình hướng dẫn ngắn. Đầu tiên là tài khoản admin, bao gồm tên thật, tên người dùng, email và mật khẩu mạnh; đây là tài khoản duy nhất hiện có, vì vậy đừng làm mất nó. Tiếp theo là thông tin tổ chức và máy chủ, bao gồm tên, ngành nghề, quy mô, tên trang web và ngôn ngữ mặc định; phần này chỉ mang tính hình thức, hãy điền vào và tiếp tục. Sau đó là lựa chọn quan trọng: đăng ký workspace này với Rocket.Chat Cloud, hoặc giữ ở chế độ standalone (độc lập).

Việc đăng ký cho phép sử dụng thông báo đẩy (push notification) trên thiết bị di động thông qua gateway của Rocket.Chat và marketplace của add-on, đổi lại bạn phải chấp nhận kết nối control-plane với cloud của Rocket.Chat. Chế độ standalone giữ cho máy chủ hoàn toàn riêng tư và không phụ thuộc vào bên ngoài, nhưng thông báo đẩy trên iOS và Android sẽ không hoạt động, vì Apple và Google không cho phép ứng dụng tự build giữ chứng chỉ push, các ứng dụng chính thức phải định tuyến qua cloud gateway. Hãy chọn standalone nếu quyền riêng tư là ưu tiên hàng đầu và người dùng của bạn chỉ sử dụng web app; hãy chọn đăng ký nếu thông báo đẩy trên di động là yêu cầu bắt buộc. Bạn có thể thay đổi lựa chọn này sau đó trong phần Admin.

Khóa hệ thống trước khi cho phép người dùng truy cập

Rocket.Chat mặc định được phát hành với tính năng đăng ký mở, trong đó Registration Form được đặt là Public, vì vậy bất kỳ ai tìm thấy URL đều có thể tạo tài khoản. Trên một hostname công khai, đây là một lỗ hổng bảo mật. Hãy truy cập Admin → Settings → Accounts → Registration và đặt Registration Form thành Disabled để bạn có thể tự tạo tài khoản hoặc gửi link mời, hoặc đặt thành Secret URL. Trong khi ở đó, hãy tắt Allow Anonymous ReadAllow Anonymous Write trừ khi bạn thực sự muốn có một kênh công khai chỉ cho phép đọc. Nếu việc tạo thủ công từng tài khoản gây mất thời gian và đây không phải là dịch vụ duy nhất mà nhóm của bạn sử dụng, hãy trỏ tính năng đăng nhập OAuth của Rocket.Chat vào một server Authentik SSO tự host, nhờ đó việc quản lý người dùng mới và người dùng rời đi được thực hiện tập trung tại một nơi thay vì phải làm trên từng ứng dụng.

Bạn cũng cần quyết định nơi lưu trữ các tệp tải lên. Mặc định của File Upload là GridFS, lưu trữ mọi hình ảnh và tệp đính kèm ngay bên trong MongoDB. Cách này đơn giản, nhưng nó khiến cơ sở dữ liệu và mọi mongodump bạn thực hiện sẽ tăng dung lượng không giới hạn khi người dùng gửi ảnh chụp màn hình. Trong mục Admin → Settings → File Upload, bạn có thể chuyển bộ lưu trữ sang filesystem cục bộ hoặc một bucket tương thích với S3, đồng thời thiết lập kích thước tệp tối đa hợp lý. Nếu nhóm của bạn thường xuyên trao đổi toàn bộ thư viện ảnh thay vì chỉ thỉnh thoảng gửi ảnh chụp màn hình, những dữ liệu đó nên được lưu ở một server ảnh chuyên dụng thay vì trong cơ sở dữ liệu chat, và bài viết so sánh PhotoPrism và Immich sẽ giúp bạn cân nhắc chi phí RAM so với các lệnh backup cần thiết cho từng loại. Với một nhóm nhỏ, GridFS là đủ dùng; chỉ cần lưu ý rằng các bản backup của bạn sẽ ngày càng nặng hơn theo thời gian.

Sao lưu với mongodump

Toàn bộ dữ liệu của bạn nằm trong volume mongodb_data. Đừng chỉ sao chép volume khi database đang chạy, hãy thực hiện một bản dump nhất quán bằng mongodump, xuất trực tiếp ra một file trên host:

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

File lưu trữ nén gzipped duy nhất đó là toàn bộ không gian làm việc của bạn: người dùng, kênh, tin nhắn, cài đặt và cả các file nếu bạn để upload trên GridFS. Nếu bạn đã chuyển các file upload sang filesystem hoặc S3, hãy sao lưu kho lưu trữ đó riêng biệt. Để khôi phục trên một stack mới, hãy khởi tạo replica set trước, sau đó chạy:

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

Hãy sao chép file lưu trữ ra khỏi máy chủ, lưu vào object storage, một server khác, bất cứ nơi nào mà nếu VPS bị hỏng thì bản sao lưu vẫn an toàn. Hãy chạy lệnh dump từ cron hàng đêm. Một bản sao lưu chưa từng được khôi phục chỉ là hy vọng, không phải là bản sao lưu thực sự; hãy thực hành khôi phục một lần trên một VPS dùng thử để đảm bảo nó hoạt động trước khi bạn thực sự cần đến.

Nâng cấp: ghim tag, đọc ghi chú, tuân thủ ma trận Mongo

Hai quy tắc giúp việc nâng cấp trở nên đơn giản. Đầu tiên, hãy nâng cấp Rocket.Chat từng phiên bản major một. Nó thực hiện migration schema khi khởi động và cố tình từ chối nhảy vọt phiên bản; nếu bạn cố nâng từ 6.x lên thẳng 8.x, nó sẽ dừng lại với lỗi migration thay vì làm hỏng dữ liệu của bạn. Hãy cập nhật image tag lên bản release mới nhất của phiên bản major kế tiếp, đọc ghi chú thay đổi (breaking changes) của bản đó, chạy docker compose up -d, và theo dõi log để đảm bảo quá trình migration hoàn tất trước khi tiếp tục. Thứ hai, hãy tuân thủ ma trận hỗ trợ của MongoDB. Mỗi bản release Rocket.Chat hỗ trợ một tập hợp các phiên bản MongoDB cụ thể, và curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions sẽ cho bạn biết phiên bản nào được hỗ trợ. Khi bạn nâng cấp MongoDB, ví dụ từ 7.0 lên 8.0, hãy nâng từng phiên bản major một và thiết lập feature-compatibility version sau mỗi bước. Trên MongoDB 8.0, lệnh này yêu cầu một confirm: true rõ ràng, nếu không nó sẽ từ chối và hiển thị thông báo yêu cầu bạn chạy lại lệnh với flag xác nhận:

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

Hãy thực hiện mongodump trước mỗi lần nâng cấp bất kỳ thành phần nào. Đó là toàn bộ chính sách bảo hiểm của bạn.

Các chế độ lỗi, với các chuỗi chính xác

Rocket.Chat bị lặp lại quá trình khởi động ngay sau docker compose up, và docker compose logs rocketchat bị lấp đầy bởi MongoServerSelectionError. MongoDB đang chạy nhưng driver không thể chọn được primary, và chuỗi chính xác sẽ cho bạn biết bạn đã mắc lỗi gì. Server selection timed out after 30000 ms với topology type là ReplicaSetNoPrimary nghĩa là bạn chưa chạy rs.initiate(), tập hợp này chưa có cấu hình. getaddrinfo ENOTFOUND theo sau bởi một hash ngẫu nhiên nghĩa là bạn đã khởi tạo mà không có host: "mongodb:27017" rõ ràng, vì vậy MongoDB đã quảng bá một hostname container không thể phân giải. Chẩn đoán bằng sudo docker compose exec mongodb mongosh --eval 'rs.status()': nếu nó báo lỗi MongoServerError: no replset config has been received, hãy khởi tạo tập hợp; nếu nó hiển thị một thành viên có name là một hash ngẫu nhiên, hãy khởi tạo lại với tên service.

Giao diện web tải được nhưng quá trình đăng nhập xoay vòng mãi mãi và không bao giờ hoàn tất. Mở console của trình duyệt và bạn sẽ thấy WebSocket connection to 'wss://chat.example.com/websocket' failed. Đây gần như luôn là lỗi không khớp ROOT_URL hoặc proxy không chuyển tiếp các header nâng cấp (upgrade headers). Xác nhận ROOT_URL bằng với địa chỉ công khai chính xác bao gồm cả https://, và block location trong nginx của bạn đã thiết lập UpgradeConnection "upgrade" với proxy_http_version 1.1. Thay đổi một trong hai và chạy lại docker compose up -d.

Container liên tục bị chết và docker compose ps cho thấy nó Restarting. docker compose logs bị cắt ngang dòng và sudo dmesg | tail hiển thị Out of memory: Killed process 12345 (mongod) từ oom-killer; mã thoát là 137. Máy chủ đã hết RAM. Cách khắc phục thực sự là nâng cấp VPS lớn hơn, tối thiểu 4 GB. Để tạm thời, hãy thêm swap và giới hạn cache của MongoDB bằng --wiredTigerCacheSizeGB 1 trong command của nó, nhưng swap chỉ trì hoãn lần OOM tiếp theo khi có tải thực tế:

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

docker compose up thất bại với Error response from daemon: driver failed programming external connectivity ... bind: address already in use. Có thứ gì đó đang chiếm cổng 3000, thường là một container Rocket.Chat trước đó chưa dừng hẳn, hoặc một ứng dụng khác. Tìm nó bằng sudo ss -ltnp | grep :3000, dừng tiến trình hoặc container đó, hoặc thay đổi phía host của mapping thành 127.0.0.1:3001:3000 và cập nhật proxy_pass của proxy để khớp với cổng mới.

FAQ

Rocket.Chat có thực sự cần MongoDB replica set không?

Có, ngay cả với một máy chủ duy nhất chỉ có một node cơ sở dữ liệu. Rocket.Chat gửi tin nhắn theo thời gian thực bằng cách sử dụng MongoDB change streams, và change streams là tính năng chỉ có trên replica set, một standalone mongod không thể mở được. Bạn không cần nhiều máy; bạn chỉ cần chạy một container MongoDB khởi động với --replSet rs0 và khởi tạo một set gồm một thành viên bằng rs.initiate(). Nếu bỏ qua bước này, driver sẽ không bao giờ tìm thấy primary, khiến Rocket.Chat bị lặp lại vòng khởi động với MongoServerSelectionError: Server selection timed out và không bao giờ hoàn tất quá trình boot.

Rocket.Chat tự host cần bao nhiêu RAM?

Hãy lên kế hoạch với 4 GB là mức tối thiểu thực tế và 8 GB cho một đội ngũ bận rộn. Tiến trình Node của Rocket.Chat sử dụng khoảng 1 đến 1.5 GB và MongoDB chiếm khoảng một nửa lượng RAM còn lại cho WiredTiger cache của nó, vì vậy trên một máy 2 GB, hai tiến trình này sẽ xung đột và out-of-memory killer sẽ kết thúc mongod dưới bất kỳ tải thực tế nào, hiển thị Killed trong log và mã thoát 137. 2 GB chỉ đủ để đánh giá phần mềm với một vài người dùng thử nghiệm.

Làm thế nào để đặt Rocket.Chat phía sau HTTPS?

Chạy một reverse proxy trên cùng VPS để thực hiện TLS termination và chuyển tiếp đến 127.0.0.1:3000, đồng thời đặt ROOT_URL của container thành địa chỉ https:// công khai của bạn. Proxy phải chuyển tiếp các header WebSocket upgrade nếu không quá trình đăng nhập sẽ bị treo. Certbot với nginx là thiết lập đơn ứng dụng đơn giản nhất; Traefik sẽ gọn gàng hơn nếu bạn chạy nhiều container phía sau một proxy và muốn quản lý chứng chỉ tự động.

Làm thế nào để sao lưu Rocket.Chat tự host?

Hãy thực hiện một bản dump cơ sở dữ liệu nhất quán bằng mongodump thay vì sao chép volume: docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz. Bản lưu trữ đó chứa người dùng, kênh, tin nhắn và cài đặt, cộng với các tệp đã tải lên nếu bạn để lưu trữ trên GridFS. Hãy sao chép nó ra khỏi máy chủ, tự động hóa hàng đêm bằng cron và diễn tập một quy trình mongorestore trên một máy chủ dùng thử để đảm bảo việc khôi phục thực sự hoạt động.

Làm thế nào để nâng cấp Rocket.Chat mà không làm hỏng MongoDB?

Hãy nâng cấp Rocket.Chat từng phiên bản major một, nó thực hiện các migration khi khởi động và từ chối bỏ qua các bản major, đồng thời đọc ghi chú của mỗi bản release trước khi thay đổi tag image đã ghim. Kiểm tra xem phiên bản MongoDB nào được hỗ trợ bởi bản release mục tiêu của bạn với curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions, và khi bạn di chuyển MongoDB, hãy thực hiện từng bước major một và đặt setFeatureCompatibilityVersion bằng confirm: true sau mỗi lần chuyển đổi. Luôn luôn thực hiện một bản mongodump trước tiên.