Docker Compose দিয়ে Rocket.Chat সেটআপ করার নিয়ম
VPS-এ Docker Compose ব্যবহার করে Rocket.Chat এবং MongoDB replica set সেটআপ করার সম্পূর্ণ গাইড। TLS এবং ব্যাকআপসহ সব এরর সমাধানের উপায় এখানে পাবেন।
আপনি যা তৈরি করছেন
একটি নিজস্ব প্রাইভেট টিম চ্যাট: Docker Compose ব্যবহার করে আপনার নিজস্ব VPS-এ চলা Rocket.Chat। এটি TLS দ্বারা সুরক্ষিত এবং প্রতিটি মেসেজ একটি MongoDB ডাটাবেসে সংরক্ষিত থাকে, যা আপনি ব্যাকআপ নিতে এবং মুভ করতে পারবেন। Rocket.Chat হলো Slack এবং Teams-এর একটি উন্নত open-source বিকল্প — চ্যানেল, ডিরেক্ট মেসেজ, থ্রেড, ফাইল শেয়ারিং এবং ভয়েস ও ভিডিও সুবিধা; এই সবকিছুই আপনার ভাড়া করা এবং নিয়ন্ত্রিত হার্ডওয়্যারে চলবে। অ্যাপ্লিকেশনটি একটি single container যা মাত্র কয়েক মিনিটে চালু করা যায়। যেকোনো সমস্যা মূলত এর পাশের ডাটাবেসে ঘটে, তাই এই গাইডের বেশিরভাগ অংশ MongoDB নিয়ে। বিশেষ করে একটি বিষয় যা প্রথমবার ব্যবহারকারীদের অবাক করে: Rocket.Chat কোনো standalone MongoDB-এর সাথে চলবে না। এর জন্য একটি replica set প্রয়োজন, এমনকি যদি সেই "set" টি একটি single node হয় তবুও।
Prerequisites, এবং RAM গণিত যা কেউ আপনাকে বলবে না
সঠিকভাবে সার্ভারের সাইজ নির্ধারণ করুন। একটি ছোট টিমের জন্য বাস্তবসম্মত সর্বনিম্ন রিকয়ারমেন্ট হলো 2 vCPU এবং 4 GB RAM। Rocket.Chat-এর Node.js প্রসেসটির নিজস্ব জন্য প্রায় 1 থেকে 1.5 GB প্রয়োজন হয়, এবং MongoDB-এর WiredTiger cache ডিফল্টভাবে বাকি থাকা RAM-এর প্রায় অর্ধেক ব্যবহার করে নেয়। একটি 2 GB VPS-এ বুট হওয়ার সময় এরা দুজনেই জায়গা পায়, কিন্তু বাস্তব ট্রাফিক আসার সাথে সাথেই সংঘর্ষ শুরু হয়: MongoDB তার cache বাড়ায়, Node তার heap বাড়ায়, kernel-এর কাছে পর্যাপ্ত pages থাকে না, এবং out-of-memory killer সবচেয়ে বড় প্রসেসটিকে বন্ধ করে দেয় — যা সাধারণত mongod হয়। কন্টেইনারটি Killed প্রিন্ট করে, Docker সেটি রিস্টার্ট দেয়, এবং আপনি এমন একটি চ্যাট সার্ভার পান যা সামান্য লোডেই প্রতি কয়েক মিনিট অন্তর বন্ধ হয়ে যায়। মাত্র দুজন ব্যবহারকারীর জন্য পরীক্ষা করার জন্য 2 GB যথেষ্ট; কিন্তু এটি কোনো টিমের সার্ভার নয়। কমপক্ষে 4 GB দিয়ে শুরু করুন, এবং যদি আপনি ডজনখানেক concurrent users, ভিডিও কল, অথবা ক্রমবর্ধমান upload history আশা করেন, তবে 8 GB দিন।
শুরু করার আগে আপনার আরও তিনটি জিনিস প্রয়োজন। একটি ডোমেইন নাম যার A record VPS-এর public IP-তে পয়েন্ট করা আছে — Rocket.Chat-এর real-time ফিচার এবং mobile client-গুলোর জন্য একটি স্থিতিশীল hostname প্রয়োজন, শুধু IP নয়। সার্ভার firewall এবং আপনার provider-এর network firewall উভয় ক্ষেত্রেই 80 এবং 443 Port খোলা থাকতে হবে, যা বেশিরভাগ প্যানেলে একটি আলাদা কন্ট্রোল। এবং root বা sudo অ্যাক্সেসসহ একটি ফ্রেশ Ubuntu 24.04 KVM VPS। আপনি যদি এখনও সিদ্ধান্ত নিতে না পারেন যে চ্যাট সার্ভার চালানো আপনার জন্য সঠিক প্রথম সার্ভিস কি না, তবে 2026 সালে কোনগুলো self-hosting করার যোগ্য তার গাইড বিষয়টি বিশ্লেষণ করে দেখাবে।
Docker engine এবং Compose plugin ইনস্টল করুন
Ubuntu-এর ডিফল্ট docker.io প্যাকেজ অথবা পুরনো standalone docker-compose Python binary ব্যবহার করবেন না। Docker-এর নিজস্ব apt repository ব্যবহার করুন। আধুনিক Compose হলো একটি Docker plugin যা docker compose হিসেবে কল করা হয় — এখানে হাইফেন নয়, বরং একটি স্পেস ব্যবহার করুন। পুরনো docker-compose v1 এর সাপোর্ট শেষ হয়ে গেছে এবং এটি নিচের healthcheck ও dependency syntax সঠিকভাবে হ্যান্ডেল করতে পারে না।
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 versiondocker compose version কমান্ডটি Docker Compose version v2.x এর মতো আউটপুট দিলে সেটিই সঠিক। যদি docker: 'compose' is not a docker command এর মতো এরর দেখায়, তবে বুঝবেন plugin ইনস্টল হয়নি। এর ফলে পরবর্তীতে জটিল সমস্যা দেখা দিতে পারে — তাই এখনই এটি ঠিক করুন।
Compose file: Single-node replica set হিসেবে MongoDB
এই অংশটি মানুষ ভুল করে, তাই এটি সাবধানে পড়ুন। Rocket.Chat রিয়েল টাইমে কানেক্টেড ক্লায়েন্টদের কাছে নতুন মেসেজ পাঠানোর জন্য MongoDB change streams ব্যবহার করে। change streams শুধুমাত্র একটি replica set-এ উপলব্ধ। আপনি যদি Rocket.Chat-কে একটি সাধারণ standalone mongod-এর সাথে কানেক্ট করার চেষ্টা করেন, তবে এটি কানেক্ট হবে কিন্তু change stream খুলতে ব্যর্থ হবে এবং চিরস্থায়ীভাবে restart-loop-এ পড়ে থাকবে। এর সমাধান খুব জটিল নয়: আপনি একটি সাধারণ MongoDB container চালাবেন, তবে এটি --replSet দিয়ে শুরু করবেন এবং তারপর একটি one-member set ইনিশিয়ালাইজ করবেন।
একটি working directory এবং একটি 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 port-টি 127.0.0.1:3000-এ পাবলিশ করা হয়েছে, 0.0.0.0-এ নয় — অ্যাপটির নিজস্ব কোনো TLS নেই, তাই একই মেশিনে থাকা reverse proxy ছাড়া অন্য কিছুর মাধ্যমে এটি অ্যাক্সেস করা উচিত নয়; প্রতিটি interface-এ এটি bind করলে plaintext login page সরাসরি পাবলিক ইন্টারনেটে চলে আসবে। MongoDB হোস্টের সাথে কোনোভাবেই পাবলিশ করা হয়নি; এটি শুধুমাত্র Compose-এর internal network-এ mongodb নামে অ্যাক্সেস করা সম্ভব, যা মূলত MONGO_URL ব্যবহার করা hostname। MONGO_URL-এ ?replicaSet=rs0 রয়েছে — এটি না থাকলে driver সার্ভারটিকে standalone হিসেবে গণ্য করবে যদিও এটি একটি replica set, ফলে change streams কাজ করবে না। MONGO_OPLOG_URL হলো local database যা oplog ধারণ করে; আধুনিক Rocket.Chat change streams পছন্দ করে, তবে এটি সেট করে রাখা ক্ষতিকারক নয় এবং এটি পুরনো code path-এর জন্য সহায়ক। depends_on এখানে condition: service_healthy ব্যবহার করে, তাই Compose Rocket.Chat শুরু করার আগে MongoDB-এর ping উত্তরের জন্য অপেক্ষা করে — healthcheck-এর কাজ এটাই।
উভয় ইমেজের জন্য নির্দিষ্ট version tag ব্যবহার করুন — এখানে mongo:8.0 এবং Rocket.Chat-এর একটি নির্দিষ্ট রিলিজ যেমন 8.5.1 — এবং কখনো :latest ব্যবহার করবেন না, কারণ এটি একটি unattended docker pull-কে অনিচ্ছাকৃত এবং un-migratable upgrade-এ পরিণত করে। ট্যাগ ফিক্স করার আগে বর্তমান stable Rocket.Chat রিলিজ এবং এর সমর্থিত MongoDB version যাচাই করে নিন। Rocket.Chat প্রতিটি রিলিজের জন্য একটি machine-readable info document পাবলিশ করে: curl -s https://releases.rocket.chat/8.5.1/info | jq '{compatibleMongoVersions, lts}' রিলিজ 8.5.1-এর জন্য compatibleMongoVersions: ["8.0"] রিটার্ন করে, তাই mongo:8.0 হলো একমাত্র সমর্থিত engine, সাথে একটি lts flag যা আপনাকে জানাবে যে রিলিজটি long-term-support বিল্ড কিনা যা আপনার সার্ভারের জন্য উপযোগী।
Replica set initialise করুন
Stack টি চালু করুন:
sudo docker compose up -dRocket.Chat সাথে সাথে crash করা শুরু করবে এবং Docker এটিকে বারবার restart করতে থাকবে — এটি স্বাভাবিক, কারণ replica set এখনও তৈরি করা হয়নি। এটি একবার ম্যানুয়ালি তৈরি করুন:
sudo docker compose exec mongodb mongosh --eval 'rs.initiate({_id: "rs0", members: [{_id: 0, host: "mongodb:27017"}]})'সঠিক ফলাফল হলো { ok: 1 }। কয়েক সেকেন্ডের মধ্যে single nodeটি নিজেকে primary হিসেবে নির্বাচন করবে; এটি নিশ্চিত করতে নিচের কমান্ডটি ব্যবহার করুন:
sudo docker compose exec mongodb mongosh --quiet --eval 'rs.status().members[0].stateStr'আপনার PRIMARY দেখা উচিত। এই পুরো পেজের সবচেয়ে গুরুত্বপূর্ণ বিষয় হলো host: "mongodb:27017" argument। আপনি যদি কোনো members list ছাড়া শুধু rs.initiate() চালান, তবে MongoDB কন্টেইনারের internal hostname অনুযায়ী replica set টি ঘোষণা করে — যা a1b2c3d4e5f6 এর মতো একটি random hash। Rocket.Chat যখন তার নিজস্ব কন্টেইনার থেকে কানেক্ট করার চেষ্টা করে, তখন সে ওই নামটি resolve করতে পারে না; ফলে MongoDB driver DNS error দেখায় এবং MongoServerSelectionError: getaddrinfo ENOTFOUND a1b2c3d4e5f6 লগ করার মাধ্যমে লুপে পড়ে থাকে। সবসময় আপনার MONGO_URL এর সাথে মিলে যায় এমন explicit service name দিয়ে এটি শুরু করুন।
প্রথম বুট: প্রসেসটি পর্যবেক্ষণ করুন
সেটটি primary হয়ে গেলে, Rocket.Chat এর পরবর্তী restart সফলভাবে সম্পন্ন হবে এবং এটি প্রথমবার চালানোর জন্য প্রয়োজনীয় migrations শুরু করবে। লগগুলো অনুসরণ করুন:
sudo docker compose logs -f rocketchatআপনি যে লাইনের জন্য অপেক্ষা করছেন সেটি হলো startup banner:
+--------------------------------------------+
SERVER RUNNING
Rocket.Chat Version: 8.5.1
NodeJS Version: 22.22.3 - x64
+--------------------------------------------+প্রথম বুট প্রক্রিয়াটি ধীরগতির হতে পারে — অ্যাপটি database migrations সম্পন্ন করে এবং indexes তৈরি করে, তাই দুশ্চিন্তা করার আগে এক বা দুই মিনিট অপেক্ষা করুন। যদি লগটি MongoServerSelectionError: Server selection timed out after 30000 ms বার বার দেখায় এবং topology description হিসেবে ReplicaSetNoPrimary থাকে, তবে বুঝতে হবে replica setটি initiate করা হয়নি; যদি এটি একটি random hash এর সাথে getaddrinfo ENOTFOUND দেখায়, তবে এটি ভুল host দিয়ে initiate করা হয়েছে। যেকোনো ক্ষেত্রেই, আগের ধাপে ফিরে যান। যখন আপনি SERVER RUNNING দেখতে পাবেন, তখন Rocket.Chat 127.0.0.1:3000 এ listening অবস্থায় থাকবে এবং এখন এর সামনে একটি সঠিক hostname এবং TLS সেট করার সময় হয়েছে।
এটিকে TLS-এর আড়ালে রাখুন
Rocket.Chat-কে কখনো plain HTTP-তে প্রকাশ করবেন না। http://-এর মাধ্যমে একবার লগ-ইন করলে আপনি আপনার admin password পথের যেকোনো ব্যক্তির কাছে দিয়ে দিচ্ছেন। একই সার্ভারে একটি reverse proxy-তে TLS terminate করুন এবং 127.0.0.1:3000-এ forward করুন। দুটি বিষয় গুরুত্বপূর্ণ: proxy-টিকে অবশ্যই WebSocket upgrade headers forward করতে হবে, কারণ Rocket.Chat real-time এবং এই headers ছাড়া এটি কাজ করবে না; এবং container-এর ROOT_URL অবশ্যই ব্যবহারকারীরা টাইপ করা public HTTPS অ্যাড্রেসের সাথে হুবহু মিলতে হবে।
প্রথমে একটি plain HTTP nginx server block দিয়ে শুরু করুন যা app-এ proxy করবে এবং upgrade headers forward করবে। এটি /etc/nginx/sites-available/rocketchat হিসেবে সেভ করুন, sites-enabled-এ symlink করুন এবং 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;
}
}আপাতত এটিকে port 80-তে রাখুন — listen 443 ssl; সহ এবং কোনো certificate ছাড়া একটি block এমনকি sudo nginx -t পাস করতে পারবে না। nginx (sudo nginx -t && sudo systemctl reload nginx) reload করুন, তারপর certificate ইস্যু করুন। Ubuntu-তে সবচেয়ে সহজ পদ্ধতি হলো Certbot এবং nginx দিয়ে Let's Encrypt TLS certificates: certbot --nginx উপরের block-টি পরিবর্তন করে listen 443 ssl;, ssl_certificate lines, এবং একটি automatic 80-to-443 redirect যোগ করে দেয়, এবং এটি আপনার জন্য renewal শিডিউল করে দেয়। আপনি যদি ইতিমধ্যে একটি proxy-র পেছনে অনেকগুলো container চালান, তবে অনেক Docker app-এর জন্য automatic TLS সহ Traefik একটি পরিচ্ছন্ন বিকল্প — rocketchat service-এ router এবং service labels যোগ করুন এবং Traefik আপনার জন্য certificate রিকোয়েস্ট এবং রিনিউ করবে, এতে কোনো nginx block লাগবে না। যে পদ্ধতিই ব্যবহার করুন না কেন, compose.yml-এ ROOT_URL কে https://chat.example.com হিসেবে সেট করুন এবং sudo docker compose up -d পুনরায় চালান যাতে container পরিবর্তনটি গ্রহণ করতে পারে। আপনি যদি চান সার্ভারটি public internet-এর পরিবর্তে শুধুমাত্র আপনার নিজস্ব নেটওয়ার্ক থেকে অ্যাক্সেসযোগ্য হোক, তবে এটিকে একটি VPS-এ self-hosted WireGuard VPN দিয়ে যুক্ত করুন এবং proxy-টিকে tunnel address-এর সাথে bind করুন।
প্রথমবার ব্যবহারের সেটআপ উইজার্ড
https://chat.example.com এবং Rocket.Chat වෙත যান। Rocket.Chat আপনাকে একটি ছোট উইজার্ডের মাধ্যমে নির্দেশনা দেবে। প্রথমে, admin account তৈরি করুন — একটি আসল নাম, username, email এবং একটি শক্তিশালী password দিন; এটিই একমাত্র অ্যাকাউন্ট থাকবে, তাই এটি হারিয়ে ফেলবেন না। এরপর, organisation and server info প্রদান করুন — নাম, industry, size, সাইটের নাম এবং default language; এগুলো কেবল সাজসজ্জার জন্য, তথ্যগুলো দিয়ে পরবর্তী ধাপে যান। এরপর একটি গুরুত্বপূর্ণ সিদ্ধান্ত নিতে হবে: Rocket.Chat Cloud-এর সাথে এই workspace টি register করবেন, নাকি এটি standalone হিসেবে রাখবেন।
Register করার ফলে Rocket.Chat-এর gateway এবং add-on marketplace-এর মাধ্যমে mobile push notifications পাওয়া যাবে, তবে এর জন্য Rocket.Chat-এর cloud-এর সাথে একটি control-plane সম্পর্ক তৈরি হবে। Standalone মোডে সার্ভারটি সম্পূর্ণ private এবং dependency-free থাকবে, কিন্তু iOS এবং Android push notifications কাজ করবে না; কারণ Apple এবং Google কোনো self-built app-কে push certificates ব্যবহারের অনুমতি দেয় না — অফিসিয়াল অ্যাপগুলো cloud gateway-এর মাধ্যমে কাজ করে। যদি গোপনীয়তা (privacy) আপনার প্রধান লক্ষ্য হয় এবং ব্যবহারকারীরা web app ব্যবহার করেন, তবে standalone বেছে নিন; আর যদি mobile push অপরিহার্য হয়, তবে registration বেছে নিন। আপনি পরবর্তীতে Admin সেকশন থেকে এই সিদ্ধান্ত পরিবর্তন করতে পারবেন।
কাউকে আমন্ত্রণ জানানোর আগে নিরাপত্তা নিশ্চিত করুন
Rocket.Chat ডিফল্টভাবে open registration on অবস্থায় থাকে — এর ফলে Registration Form হিসেবে Public সেট করা থাকে, তাই যে কেউ URL খুঁজে পেলে একটি অ্যাকাউন্ট তৈরি করতে পারে। পাবলিক hostname-এর ক্ষেত্রে এটি একটি উন্মুক্ত প্রবেশপথের মতো কাজ করে। Admin → Settings → Accounts → Registration-এ যান এবং Registration Form অপশনটি Disabled হিসেবে সেট করুন, যাতে আপনি নিজে হাতে বা ইনভাইট লিঙ্ক দিয়ে অ্যাকাউন্ট তৈরি করতে পারেন, অথবা Secret URL হিসেবে সেট করুন। এছাড়া, আপনি যদি বিশেষভাবে কোনো পাবলিক রিড-অনলি চ্যানেল না চান, তবে Allow Anonymous Read এবং Allow Anonymous Write অপশন দুটি বন্ধ করে দিন।
আপলোড করা ফাইলগুলো কোথায় জমা হবে তাও ঠিক করে নিন। ডিফল্ট File Upload স্টোরেজ হলো GridFS, যা প্রতিটি ছবি এবং অ্যাটাচমেন্ট সরাসরি MongoDB-এর ভেতরে সংরক্ষণ করে। এটি সহজ পদ্ধতি, কিন্তু এর মানে হলো ব্যবহারকারীরা স্ক্রিনশট পেস্ট করার সাথে সাথে আপনার ডাটাবেস — এবং আপনার প্রতিটি mongodump — ক্রমাগত বড় হতে থাকবে। Admin → Settings → File Upload-এর অধীনে আপনি স্টোরেজ হিসেবে local filesystem অথবা S3-compatible bucket ব্যবহার করতে পারেন এবং ফাইলের সর্বোচ্চ সাইজ নির্ধারণ করে দিতে পারেন। ছোট টিমের জন্য GridFS ঠিক আছে; তবে মনে রাখবেন যে সময়ের সাথে সাথে আপনার ব্যাকআপ ফাইলের আকার বাড়তে থাকবে।
mongodump দিয়ে ব্যাকআপ গ্রহণ
আপনার সমস্ত ডেটা mongodb_data volume-এ থাকে। ডাটাবেস চলাকালীন সরাসরি volume কপি করবেন না — mongodump ব্যবহার করে একটি consistent dump নিন এবং হোস্টের একটি ফাইলে stream করুন:
sudo docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > rocketchat-$(date +%F).archive.gzএই একটি gzipped archive-ই আপনার সম্পূর্ণ workspace: users, channels, messages, settings, এবং — যদি আপনি GridFS-এ uploads রেখে থাকেন — তবে ফাইলগুলোও। আপনি যদি uploads গুলো filesystem বা S3-তে সরিয়ে নেন, তবে সেই স্টোরটি আলাদাভাবে ব্যাকআপ নিন। একটি নতুন stack-এ restore করতে প্রথমে replica set initialize করুন, তারপর:
sudo docker compose exec -T mongodb mongorestore --archive --gzip --drop < rocketchat-2026-07-15.archive.gzArchive ফাইলটি অন্য কোনো ডিভাইসে কপি করে রাখুন — object storage, অন্য কোনো server, বা এমন কোনো জায়গা যেখানে VPS নষ্ট হয়ে গেলেও ব্যাকআপটি হারিয়ে যাবে না — এবং প্রতি রাতে cron দিয়ে dump রান করুন। যে ব্যাকআপ কখনো restore করা হয়নি, তা কেবল একটি আশা মাত্র, প্রকৃত ব্যাকআপ নয়; তাই প্রয়োজন হওয়ার আগেই একটি throwaway VPS-এ একবার restore করার প্র্যাকটিস করে নিন।
Upgrades: pin tags, read the notes, respect the Mongo matrix
আপগ্রেড প্রক্রিয়া সহজ রাখার জন্য দুটি নিয়ম মেনে চলুন। প্রথমত, Rocket.Chat প্রতিবার মাত্র একটি major version আপগ্রেড করুন। এটি boot হওয়ার সময় schema migration সম্পন্ন করে এবং সরাসরি major version পরিবর্তন করতে দেয় না; আপনি যদি 6.x থেকে সরাসরি 8.x এ যাওয়ার চেষ্টা করেন, তবে ডেটা নষ্ট হওয়ার পরিবর্তে এটি migration error দেখাবে। ইমেজ ট্যাগটি পরবর্তী major version-এর সর্বশেষ release-এ পরিবর্তন করুন, breaking changes সম্পর্কে জানতে সেই release-এর notes পড়ুন, docker compose up -d চালান, এবং পরবর্তী ধাপে যাওয়ার আগে logs-এ migration শেষ হওয়া নিশ্চিত করুন। দ্বিতীয়ত, MongoDB support matrix মেনে চলুন। প্রতিটি Rocket.Chat release নির্দিষ্ট কিছু MongoDB version সাপোর্ট করে এবং curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions আপনাকে তা জানিয়ে দেবে। আপনি যখন MongoDB পরিবর্তন করবেন — যেমন 7.0 থেকে 8.0 — তখন প্রতিবার মাত্র একটি major version হিসেবে পরিবর্তন করুন এবং প্রতিটি ধাপের পর feature-compatibility version সেট করুন। MongoDB 8.0-এ এই কমান্ডটি চালানোর জন্য একটি explicit confirm: true প্রয়োজন, অন্যথায় এটি confirmation flag সহ পুনরায় চালানোর নির্দেশ দিয়ে error দেখাবে:
sudo docker compose exec mongodb mongosh --eval 'db.adminCommand({setFeatureCompatibilityVersion: "8.0", confirm: true})'যেকোনো component আপগ্রেড করার আগে একটি mongodump নিন। এটাই আপনার একমাত্র সুরক্ষা ব্যবস্থা।
Failure modes, with the exact strings
docker compose up এর ঠিক পরেই Rocket.Chat restart-loops হতে থাকে এবং docker compose logs rocketchat একটি MongoServerSelectionError দিয়ে পূর্ণ হয়ে যায়। MongoDB চলছে কিন্তু driver কোনো primary নির্বাচন করতে পারছে না; এর সঠিক string আপনাকে আপনার ভুলটি জানিয়ে দেবে। topology type ReplicaSetNoPrimary বিশিষ্ট Server selection timed out after 30000 ms এর অর্থ হলো আপনি কখনো rs.initiate() চালাননি — সেটটির এখনও কোনো config নেই। getaddrinfo ENOTFOUND এর পরে একটি random hash দেখাচ্ছে এর অর্থ হলো আপনি explicit host: "mongodb:27017" ছাড়া initiate করেছেন, যার ফলে MongoDB একটি unresolvable container hostname প্রচার করেছে। sudo docker compose exec mongodb mongosh --eval 'rs.status()' দিয়ে পরীক্ষা করুন: যদি MongoServerError: no replset config has been received error দেখায়, তবে সেটটি initiate করুন; যদি এমন কোনো member দেখায় যার name একটি random hash, তবে service name দিয়ে পুনরায় initiate করুন।
Web UI লোড হয় কিন্তু login করার সময় অনন্তকাল ধরে ঘুরতে থাকে এবং শেষ হয় না। ব্রাউজার console খুললে আপনি WebSocket connection to 'wss://chat.example.com/websocket' failed দেখতে পাবেন। এটি প্রায় সব সময় একটি ROOT_URL mismatch অথবা এমন একটি proxy এর কারণে ঘটে যা upgrade headers forward করছে না। নিশ্চিত করুন যে ROOT_URL এর মান https:// সহ সঠিক public address এর সমান, এবং আপনার nginx location block এ Upgrade এবং Connection "upgrade" কে proxy_http_version 1.1 দিয়ে সেট করা আছে। যেকোনো একটি পরিবর্তন করে docker compose up -d পুনরায় চালান।
একটি container বারবার বন্ধ হয়ে যাচ্ছে এবং docker compose ps নির্দেশ করছে যে এটি Restarting। docker compose logs মাঝপথে কেটে যাচ্ছে এবং sudo dmesg | tail এ oom-killer থেকে Out of memory: Killed process 12345 (mongod) দেখাচ্ছে; exit code হলো 137। সার্ভারে পর্যাপ্ত RAM নেই। স্থায়ী সমাধান হলো একটি বড় VPS ব্যবহার করা — সর্বনিম্ন 4 GB। সাময়িক সমাধানের জন্য swap যোগ করুন এবং MongoDB এর command এ --wiredTigerCacheSizeGB 1 দিয়ে cache সীমাবদ্ধ করুন, তবে swap শুধুমাত্র বাস্তব লোডের সময় পরবর্তী OOM বিলম্বিত করবে:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfiledocker compose up Error response from daemon: driver failed programming external connectivity ... bind: address already in use এর কারণে ব্যর্থ হচ্ছে। পোর্ট 3000 ইতিমধ্যে অন্য কিছু দ্বারা ব্যবহৃত হচ্ছে — এটি প্রায়ই একটি পূর্ববর্তী Rocket.Chat container যা সঠিকভাবে বন্ধ হয়নি, অথবা অন্য কোনো app। sudo ss -ltnp | grep :3000 দিয়ে এটি খুঁজে বের করুন, সেই process বা container বন্ধ করুন, অথবা mapping এর host side পরিবর্তন করে 127.0.0.1:3001:3000 করুন এবং আপনার proxy এর proxy_pass পরিবর্তন করে তা মিলিয়ে নিন।
FAQ
Rocket.Chat-এর কি সত্যিই MongoDB replica set প্রয়োজন?
হ্যাঁ, এমনকি একটি মাত্র ডাটাবেস নোড বিশিষ্ট সিঙ্গেল সার্ভারের জন্যও এটি প্রয়োজন। Rocket.Chat রিয়েল টাইম মেসেজ ডেলিভারি করার জন্য MongoDB change streams ব্যবহার করে। change streams শুধুমাত্র replica-set-এ কাজ করে; একটি standalone mongod এটি করতে পারে না। আপনার একাধিক মেশিনের প্রয়োজন নেই; আপনি --replSet rs0 দিয়ে একটি MongoDB container চালাতে পারেন এবং rs.initiate() দিয়ে একটি one-member set ইনিশিয়ালাইজ করতে পারেন। এই ধাপটি বাদ দিলে driver কোনো primary খুঁজে পাবে না, ফলে Rocket.Chat MongoServerSelectionError: Server selection timed out এর কারণে restart-loop এ পড়বে এবং বুটিং সম্পন্ন করতে পারবে না।
self-hosted Rocket.Chat-এর জন্য কতটুকু RAM প্রয়োজন?
ব্যবহারিক ক্ষেত্রে সর্বনিম্ন 4 GB এবং একটি ব্যস্ত টিমের জন্য 8 GB RAM পরিকল্পনা করুন। Rocket.Chat-এর Node process প্রায় 1 থেকে 1.5 GB ব্যবহার করে এবং MongoDB তার WiredTiger cache-এর জন্য বাকি RAM-এর প্রায় অর্ধেক ব্যবহার করে। তাই 2 GB RAM বিশিষ্ট সার্ভারে এই দুটি প্রসেস সংঘর্ষে লিপ্ত হয় এবং real load এর সময় out-of-memory killer mongod কে বন্ধ করে দেয়, যার ফলে log-এ Killed এবং exit code 137 দেখা যায়। 2 GB RAM শুধুমাত্র অল্প কিছু টেস্ট ইউজার দিয়ে সফটওয়্যারটি পরীক্ষা করার জন্য যথেষ্ট।
আমি কীভাবে Rocket.Chat-কে HTTPS-এর আড়ালে (behind HTTPS) রাখব?
একই VPS-এ একটি reverse proxy চালান যা TLS terminate করবে এবং 127.0.0.1:3000-এ ফরওয়ার্ড করবে। এরপর কন্টেইনারের ROOT_URL আপনার পাবলিক https:// অ্যাড্রেস হিসেবে সেট করুন। Proxy-টিকে অবশ্যই WebSocket upgrade headers ফরওয়ার্ড করতে হবে, অন্যথায় login হ্যাং হয়ে যাবে। nginx সহ Certbot হলো সবচেয়ে সহজ single-app setup; আপনি যদি একটি proxy-র আড়ালে একাধিক container চালান এবং স্বয়ংক্রিয় সার্টিফিকেট ম্যানেজমেন্ট চান, তবে Traefik ব্যবহার করা বেশি সুবিধাজনক।
আমি কীভাবে self-hosted Rocket.Chat ব্যাকআপ নেব?
ভলিউম কপি করার পরিবর্তে mongodump দিয়ে একটি consistent database dump নিন: docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz। সেই আর্কাইভের মধ্যে ইউজার, চ্যানেল, মেসেজ এবং সেটিংস থাকবে; এছাড়া আপনি যদি storage GridFS-এ রাখেন তবে আপলোড করা ফাইলও থাকবে। আর্কাইভটি সার্ভার থেকে কপি করে নিন, cron দিয়ে প্রতি রাতে অটোমেট করুন এবং একটি পরীক্ষামূলক বক্সে mongorestore প্র্যাকটিস করুন যাতে নিশ্চিত হওয়া যায় যে রিস্টোর কাজ করছে।
MongoDB নষ্ট না করে আমি কীভাবে Rocket.Chat আপগ্রেড করব?
একবারে একটি major version করে Rocket.Chat আপগ্রেড করুন—এটি বুটিংয়ের সময় migrations চালায় এবং major version স্কিপ করা সমর্থন করে না। ইমেজ ট্যাগ পরিবর্তনের আগে প্রতিটি রিলিজের নোট পড়ুন। curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions দিয়ে আপনার টার্গেট রিলিজ কোন কোন MongoDB version সাপোর্ট করে তা যাচাই করে নিন। যখন আপনি MongoDB পরিবর্তন করবেন, প্রতিবার এক ধাপ করে বড় ভার্সনে যান এবং প্রতিটি ধাপ শেষে confirm: true দিয়ে setFeatureCompatibilityVersion সেট করুন। সবসময় আগে একটি mongodump নিন।