SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Docker Compose দিয়ে Rocket.Chat হোস্ট করার নিয়ম

Docker Compose ব্যবহার করে নিজস্ব VPS-এ Rocket.Chat সেটআপ করুন। MongoDB replica set কনফিগারেশন, TLS টার্মিনেশন এবং ডেটা ব্যাকআপের খুঁটিনাটিসহ সব সমস্যার সমাধান এখানে রয়েছে।

আপনি যা তৈরি করছেন

একটি ব্যক্তিগত team chat, যার সম্পূর্ণ মালিকানা আপনার: Docker Compose-এর অধীনে আপনার নিজের VPS-এ চলা Rocket.Chat, TLS termination-সহ, এবং প্রতিটি message এমন একটি MongoDB database-এ সংরক্ষিত থাকবে যেটির backup নেওয়া ও অন্যত্র স্থানান্তর করা যায়। Rocket.Chat হলো পরিণত open-source Slack ও Teams-এর বিকল্প। এতে channel, direct message, thread, file sharing, voice এবং video রয়েছে। সবকিছু আপনার ভাড়া নেওয়া ও নিয়ন্ত্রণ করা hardware-এ চলে। তবে এটিই একমাত্র নির্ভরযোগ্য বিকল্প নয়। আপনি যদি এখনও নির্বাচন করে থাকেন, Mattermost, Rocket.Chat, Synapse এবং Zulip-এর তুলনা পরবর্তী সময়ে সমস্যা তৈরি করে এমন বিষয়গুলোর ভিত্তিতে এগুলোকে পাশাপাশি তুলনা করে: RAM, database, mobile push, SSO এবং upgrade। Application-টি একটি single container, যা কয়েক মিনিটের মধ্যে চালু হয়। বাস্তবে যে সমস্যাগুলো দেখা দেয়, সেগুলোর বেশির ভাগই পাশের database-এ থাকে। তাই এই guide-এর বড় অংশ MongoDB নিয়ে, বিশেষ করে এমন একটি requirement নিয়ে যা প্রথমবার প্রায় সবাইকে অবাক করে: Rocket.Chat standalone MongoDB-এর বিরুদ্ধে চলবে না। এর একটি replica set প্রয়োজন, সেই "set" একটি single node হলেও।

প্রয়োজনীয়তা এবং RAM-এর সেই হিসাব, যা কেউ বলে না

সার্ভারের ক্ষমতা বাস্তবসম্মতভাবে নির্ধারণ করুন। ছোট দলের জন্য বাস্তবসম্মত সর্বনিম্ন ক্ষমতা হলো 2 vCPU এবং 4 GB RAM। Rocket.Chat-এর Node.js process-এর একার জন্য প্রায় 1 থেকে 1.5 GB RAM প্রয়োজন হয়। MongoDB-এর WiredTiger cache ডিফল্টভাবে (মোট RAM থেকে 1 GB বাদ দেওয়ার পরের মানের 50%) অথবা 0.256 GB—এই দুটির মধ্যে বড় মানটি ব্যবহার করে। এই ডিফল্ট ধরে নেয় যে mongod সম্পূর্ণ মেশিন একাই ব্যবহার করছে। হিসাবটি মোট RAM থেকে করা হয় এবং Node ইতিমধ্যে কত RAM ব্যবহার করছে তা বিবেচনা করে না। তাই 4 GB-এর সার্ভারে এর পরিমাণ হয় 1.5 GB এবং 2 GB-এর সার্ভারে প্রায় 0.5 GB। এর সঙ্গে Node-এর heap, cache-এর বাইরে mongod-এর নিজস্ব memory এবং operating system-এর প্রয়োজনীয় RAM-ও যোগ হয়। 2 GB VPS-এ boot হওয়ার সময় দুটিই কোনোভাবে চলে, কিন্তু প্রকৃত network traffic শুরু হলেই সংঘাত তৈরি হয়। MongoDB তার cache বাড়ায়, Node তার heap বাড়ায়, kernel-এর page ফুরিয়ে যায় এবং out-of-memory killer সবচেয়ে বেশি RAM ব্যবহার করা process-টিকে বন্ধ করে দেয়; সাধারণত সেটি হয় mongod। Container-এ Killed দেখা যায়, Docker সেটিকে restart করে, এবং এমন load-এ chat server প্রতি কয়েক মিনিটে বন্ধ হতে থাকে যা সহজেই সামলানোর কথা। দুইজন ব্যবহারকারীর মাধ্যমে পরীক্ষা করার জন্য 2 GB যথেষ্ট, কিন্তু team server-এর জন্য নয়। 4 GB দিয়ে শুরু করুন। কয়েক ডজন একসঙ্গে সংযুক্ত user, video call বা ক্রমবর্ধমান upload history প্রত্যাশা করলে 8 GB দিন। সার্ভারকে বহন করতে হবে এমন অন্য কিছুর জন্যও RAM বরাদ্দ রাখুন। একই VPS-এ Notion-এর মতো AFFiNE workspace চালালে একই page-এর জন্য প্রতিযোগিতা করা আরও চারটি container যোগ হবে। তাই এই container-গুলোর RAM Rocket.Chat-এর বরাদ্দ থেকে নিতে পারবেন না; অতিরিক্ত RAM হিসেবে ধরতে হবে।

শুরু করার আগে আরও তিনটি বিষয় প্রস্তুত রাখুন। VPS-এর public IP-এ নির্দেশ করা একটি A record-সহ domain name প্রয়োজন। Rocket.Chat-এর real-time feature এবং mobile client-এর জন্য bare IP নয়, একটি স্থিতিশীল hostname দরকার। Port 80 এবং 443 খোলা থাকতে হবে server firewall এবং provider-এর network firewall—দুই জায়গাতেই। বেশিরভাগ panel-এ network firewall আলাদা একটি নিয়ন্ত্রণ ব্যবস্থা। এছাড়া root অথবা sudo-সহ একটি নতুন Ubuntu 24.04 KVM VPS প্রয়োজন। chat server-ই প্রথমে চালানোর উপযুক্ত service কি না, তা নিয়ে এখনও সিদ্ধান্ত না নিলে, 2026 সালে কোন service self-host করা মূল্যবান তার নির্দেশিকা বিভিন্ন সুবিধা-অসুবিধা ব্যাখ্যা করে।

Docker engine এবং Compose plugin ইনস্টল করুন

Docker-এর নিজস্ব apt repository ব্যবহার করুন। Ubuntu যে docker.io package সরবরাহ করে, তা ব্যবহার করবেন না। পুরোনো standalone docker-compose Python binary-ও ব্যবহার করবেন না। আধুনিক Compose হলো Docker plugin, যা docker compose হিসেবে চালানো হয়। এখানে একটি space থাকে, hyphen নয়। পুরোনো docker-compose v1-এর support শেষ হয়েছে। নিচের 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 version

docker compose version থেকে একটি version line দেখা যাওয়াই গুরুত্বপূর্ণ পরীক্ষা। বর্তমান release-গুলো Docker Compose version v5.x প্রদর্শন করে। 2 October 2026-এ প্রকাশিত v5.6.0, 2026-10-10 তারিখে সর্বশেষ version ছিল। পুরোনো installation-এ এখনও v2.x দেখা যেতে পারে। Docker উভয় version সমর্থন করে। Docker-এর বর্ণনা অনুযায়ী, Compose v5 কার্যগতভাবে v2-এর সমান। Legacy v2 এবং v3 compose file format-এর সঙ্গে বিভ্রান্তি এড়াতে এর version number v5 রাখা হয়েছে। তাই এই guide-এর জন্য যেকোনো একটি ব্যবহার করা যাবে। docker: 'compose' is not a docker command error দেখালে plugin ইনস্টল হয়নি। পরে বিভ্রান্তিকর failure এড়াতে এখানেই এটি ঠিক করুন।

Compose ফাইল: single-node replica set হিসেবে MongoDB

এই অংশে মানুষ সবচেয়ে বেশি ভুল করে, তাই ধীরে পড়ুন। Rocket.Chat সংযুক্ত client-দের কাছে real time-এ নতুন message পাঠাতে MongoDB-এর change streams ব্যবহার করে, আর change streams শুধু replica set-এ উপলভ্য। Rocket.Chat-কে সাধারণ standalone mongod-এর দিকে নির্দেশ করলে এটি সংযোগ স্থাপন করবে, change stream খুলতে ব্যর্থ হবে এবং অনন্তকাল restart loop-এ চলবে। সমাধান জটিল নয়: একটি সাধারণ MongoDB container চালান, তবে সেটিকে --replSet দিয়ে শুরু করুন এবং এরপর এক সদস্যের একটি set initialise করুন।

একটি 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-এ publish করা হয়েছে, 0.0.0.0-এ নয়। অ্যাপটিতে নিজস্ব TLS নেই, তাই একই box-এর reverse proxy-ই যেন এতে পৌঁছাতে পারে; প্রতিটি interface-এ bind করলে plaintext login page সরাসরি public internet-এ উন্মুক্ত হয়ে যাবে। MongoDB host-এ মোটেও publish করা হয়নি; এটি শুধু Compose-এর internal network-এর মাধ্যমে mongodb নামের অধীনে পৌঁছানো যায়। MONGO_URL ঠিক এই hostname-টিই ব্যবহার করে। MONGO_URL-এ ?replicaSet=rs0 রয়েছে, যা set-এর নাম স্পষ্টভাবে নির্ধারণ করে; driver-গুলোর মধ্যে সামঞ্জস্যপূর্ণ আচরণের জন্য MongoDB এটি নির্ধারণ করার পরামর্শ দেয়। এটি বাদ দিলে নিজে থেকে কোনো সমস্যা হয় না: directConnection-এর default হলো false। তাই set-টি এমন একটি hostname দিয়ে initialise করা হলে, যেটি Rocket.Chat resolve করতে পারে, driver এখনও replica set শনাক্ত করে operation-গুলো primary-তে পাঠাবে। পরের section-এ সেটিই করা হয়েছে। MONGO_OPLOG_URL সেই local database-কে নির্দেশ করে যেখানে oplog থাকে; আধুনিক Rocket.Chat change streams ব্যবহার করতে পছন্দ করে, তবে এটি নির্ধারণ করলে কোনো ক্ষতি নেই এবং পুরোনো code path-গুলোও সচল থাকে। depends_on-এ condition: service_healthy ব্যবহার করা হয়েছে। ফলে MongoDB একটি ping-এর উত্তর দেওয়া পর্যন্ত Compose অপেক্ষা করে, তারপর Rocket.Chat শুরু করে। healthcheck-এর কাজ এটাই।

উভয় image-এর ক্ষেত্রে, mongo:8.0 এবং এখানে ব্যবহৃত 8.5.1-এর মতো একটি নির্দিষ্ট Rocket.Chat release-এ প্রকৃত version tag pin করুন। কখনো :latest ব্যবহার করবেন না। এটি unattended docker pull-কে অনিচ্ছাকৃত এবং migration করা যায় না এমন upgrade-এ পরিণত করে। Pin করার আগে বর্তমান stable Rocket.Chat release এবং এটি সমর্থন করে এমন MongoDB version পরীক্ষা করুন। Rocket.Chat প্রতিটি release-এর জন্য machine-readable info document প্রকাশ করে: 8.5.1-এর ক্ষেত্রে curl -s https://releases.rocket.chat/8.5.1/info | jq '{compatibleMongoVersions, lts}', compatibleMongoVersions: ["8.0"] ফেরত দেয়। এতে mongo:8.0-ই একমাত্র supported engine, পাশাপাশি একটি lts flag থাকে, যা জানায় release-টি long-term-support build কি না। server নিয়মিত তদারকি করতে না চাইলে এমন build pin করা উপযোগী। সব project versioned image প্রকাশ করে না। সে ক্ষেত্রে pin করার বিষয়টি source-এ স্থানান্তরিত হয়: openGym workout tracker self-host করা বলতে একটি নির্দিষ্ট git tag checkout করে সেখান থেকে build করা বোঝায়, পরিবর্তনশীল branch অনুসরণ করা নয়।

Replica set ইনিশিয়ালাইজ করা

স্ট্যাকটি চালু করুন:

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" আর্গুমেন্ট। যদি আপনি কোনো members লিস্ট ছাড়া সাধারণ rs.initiate() চালান, তবে MongoDB কন্টেইনারের ইন্টারনাল হোস্টনামের অধীনে replica set-এর বিজ্ঞাপন দেয়, যা a1b2c3d4e5f6-এর মতো একটি র‍্যান্ডম হ্যাশ। Rocket.Chat তার নিজস্ব কন্টেইনার থেকে কানেক্ট করার সময় সেই নামটি রিজলভ করতে পারে না, ফলে MongoDB ড্রাইভার DNS-এ ব্যর্থ হয় এবং বারবার MongoServerSelectionError: getaddrinfo ENOTFOUND a1b2c3d4e5f6 লগ করতে থাকে। সবসময় আপনার MONGO_URL-এর সাথে মিল রেখে এক্সপ্লিসিট সার্ভিস নেম দিয়ে ইনিশিয়েট করুন।

প্রথম বুট: এটি চালু হওয়া পর্যবেক্ষণ করুন

একবার সেটটি প্রাইমারি হয়ে গেলে, Rocket.Chat-এর পরবর্তী রিস্টার্ট সঠিকভাবে সম্পন্ন হয় এবং এটি প্রথমবার চালানোর জন্য প্রয়োজনীয় মাইগ্রেশন শুরু করে। লগগুলো অনুসরণ করুন:

sudo docker compose logs -f rocketchat

আপনি যে লাইনটির জন্য অপেক্ষা করছেন তা হলো স্টার্টআপ ব্যানার:

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

প্রথম বুট হতে সময় লাগে, কারণ অ্যাপটি ডাটাবেস মাইগ্রেশন চালায় এবং ইনডেক্স তৈরি করে। তাই চিন্তিত হওয়ার আগে এক বা দুই মিনিট অপেক্ষা করুন। যদি লগে বারবার MongoServerSelectionError: Server selection timed out after 30000 ms এবং তার সাথে ReplicaSetNoPrimary ধরনের টপোলজি বর্ণনা দেখা যায়, তবে বুঝতে হবে রেপ্লিকা সেটটি শুরু করা হয়নি। যদি এটি বারবার কোনো র‍্যান্ডম হ্যাশসহ getaddrinfo ENOTFOUND দেখাতে থাকে, তবে বুঝতে হবে এটি ভুল হোস্ট দিয়ে শুরু করা হয়েছে। উভয় ক্ষেত্রেই, আগের ধাপে ফিরে যান। একবার আপনি SERVER RUNNING দেখতে পেলে, বুঝবেন Rocket.Chat 127.0.0.1:3000 পোর্টে লিসেন করছে এবং এখন এর সামনে একটি সঠিক হোস্টনাম ও TLS বসানোর সময় হয়েছে।

TLS-এর পেছনে রাখুন

Rocket.Chat-কে কখনোই plain HTTP-তে উন্মুক্ত রাখবেন না। একবার http://-এর মাধ্যমে লগ ইন করলেই আপনার অ্যাডমিন পাসওয়ার্ড নেটওয়ার্কের যেকোনো ব্যক্তির কাছে চলে যেতে পারে। একই সার্ভারে একটি reverse proxy-তে TLS termination করুন এবং ট্রাফিক 127.0.0.1:3000-এ ফরোয়ার্ড করুন। দুটি বিষয় গুরুত্বপূর্ণ: প্রক্সিকে অবশ্যই WebSocket upgrade header ফরোয়ার্ড করতে হবে, কারণ Rocket.Chat রিয়েল-টাইমে কাজ করে এবং এগুলো ছাড়া তা অচল হয়ে পড়ে। এছাড়া কন্টেইনারের ROOT_URL অবশ্যই ব্যবহারকারীদের টাইপ করা পাবলিক HTTPS ঠিকানার সাথে হুবহু মিলতে হবে।

প্রথমে একটি plain HTTP nginx server block দিয়ে শুরু করুন যা অ্যাপটিতে প্রক্সি করবে এবং upgrade header ফরোয়ার্ড করবে। এটি /etc/nginx/sites-available/rocketchat হিসেবে সেভ করুন, sites-enabled-এ symlink করুন এবং রিলোড করুন:

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; ছাড়া এবং সার্টিফিকেটবিহীন কোনো ব্লক sudo nginx -t পাস করবে না। nginx রিলোড করুন (sudo nginx -t && sudo systemctl reload nginx), তারপর সার্টিফিকেট ইস্যু করুন। Ubuntu-তে সবচেয়ে সহজ উপায় হলো Certbot এবং nginx ব্যবহার করে Let's Encrypt TLS সার্টিফিকেট: certbot --nginx উপরের ব্লকটিকে সরাসরি পরিবর্তন করে, এতে listen 443 ssl;, ssl_certificate লাইনগুলো এবং স্বয়ংক্রিয় 80-to-443 রিডাইরেক্ট যোগ করে এবং আপনার জন্য রিনিউয়াল শিডিউল করে দেয়। আপনি যদি ইতিমধ্যে একটি প্রক্সির পেছনে একাধিক কন্টেইনার চালান, তবে অনেকগুলো Docker অ্যাপের জন্য স্বয়ংক্রিয় TLS সহ Traefik একটি পরিচ্ছন্ন বিকল্প। সেক্ষেত্রে rocketchat সার্ভিসে রাউটার এবং সার্ভিস লেবেল যোগ করুন, Traefik আপনার জন্য সার্টিফিকেট রিকোয়েস্ট এবং রিনিউ করবে, যার জন্য কোনো nginx ব্লকের প্রয়োজন হবে না। যে পদ্ধতিই ব্যবহার করুন, compose.yml-এ ROOT_URL-কে https://chat.example.com হিসেবে সেট করুন এবং sudo docker compose up -d পুনরায় চালান যাতে কন্টেইনারটি পরিবর্তনটি গ্রহণ করতে পারে। আপনি যদি চান সার্ভারটি পাবলিক ইন্টারনেটের পরিবর্তে শুধুমাত্র আপনার নিজস্ব নেটওয়ার্ক থেকে অ্যাক্সেসযোগ্য হোক, তবে এর সামনে একটি VPS-এ self-hosted WireGuard VPN বসান এবং প্রক্সিকে টানেল অ্যাড্রেসের সাথে bind করুন।

প্রথমবার চালুর সেটআপ wizard

https://chat.example.com-এ যান। Rocket.Chat আপনাকে একটি সংক্ষিপ্ত wizard-এর ধাপগুলো সম্পন্ন করাবে। প্রথমে admin account তৈরি করুন। এতে প্রকৃত নাম, username, email এবং একটি শক্তিশালী password দিতে হবে। এটিই একমাত্র বিদ্যমান account, তাই এটি হারাবেন না। এরপর organisation and server info দিন: নাম, industry, size, site name এবং default language। এগুলো মূলত প্রদর্শনসংক্রান্ত; তথ্য পূরণ করে পরবর্তী ধাপে যান। তারপর যে সিদ্ধান্তটি গুরুত্বপূর্ণ: এই workspace Rocket.Chat Cloud-এ register করবেন, নাকি এটিকে standalone রাখবেন।

Register করলে Rocket.Chat-এর gateway-এর মাধ্যমে mobile push notification এবং add-on marketplace ব্যবহার করা যায়। এর বিনিময়ে Rocket.Chat-এর cloud-এর সঙ্গে একটি control-plane সম্পর্ক তৈরি হয়। Gateway-এর মাধ্যমে পাঠানো push আপনার workspace-এর মাসিক সীমার মধ্যেও গণনা হয়। Standalone রাখলে server সম্পূর্ণ private এবং dependency-free থাকে। তবে official iOS ও Android app-এ আর push notification পৌঁছাবে না। Rocket.Chat-এর documentation অনুযায়ী, ওই app-গুলো কেবল তাদের cloud gateway-এর সঙ্গে কাজ করে। আবার unregistered workspace-এ gateway চালানো যায় না।

এর বিকল্প হলো mobile app-এর নিজস্ব white-labeled build তৈরি করা। Push settings-এ gateway বন্ধ করুন। নিজের APNs certificate এবং Firebase Cloud Messaging credential যোগ করুন। এরপর ব্যবহারকারীদের official app-এর বদলে আপনার app install করতে বলুন। Privacy-ই যদি প্রধান উদ্দেশ্য হয় এবং ব্যবহারকারীরা web app ব্যবহার করেন, অথবা আপনি নিজের mobile app release করতে প্রস্তুত থাকেন, তাহলে standalone বেছে নিন। Official app-এ push অপরিহার্য হলে registration বেছে নিন। পরে Admin-এর অধীনে এই সিদ্ধান্ত পরিবর্তন করতে পারবেন।

কাউকে আমন্ত্রণ জানানোর আগে নিরাপত্তা কঠোর করুন

Rocket.Chat ডিফল্টভাবে open registration চালু অবস্থায় আসে। Registration Form-এর মান Public থাকায় URL জানা যে কেউ একটি account তৈরি করতে পারে। Public hostname-এ এটি অননুমোদিত প্রবেশের সুযোগ তৈরি করে। Admin → Settings → Accounts → Registration-এ যান এবং Registration Form-এর মান Disabled করুন। এতে আপনি হাতে account তৈরি করতে পারবেন অথবা invite link ব্যবহার করতে পারবেন। চাইলে এর পরিবর্তে Secret URL নির্বাচন করতে পারেন। একই সময়ে, নির্দিষ্টভাবে public read-only channel না চাইলে Allow Anonymous Read এবং Allow Anonymous Write বন্ধ করুন। প্রতিটি account হাতে তৈরি করা যদি ঝামেলার মনে হয় এবং আপনার team যদি একাধিক service-এ login করে, তাহলে Rocket.Chat-এর OAuth login-কে self-hosted Authentik SSO server-এর দিকে নির্দেশ করুন। এতে নতুন সদস্য যোগ করা এবং সদস্যের access সরানো প্রতিটি app-এ আলাদাভাবে না করে এক জায়গা থেকেই পরিচালনা করা যাবে।

Upload কোথায় সংরক্ষিত হবে, সেটিও ঠিক করুন। ডিফল্ট File Upload storage হলো GridFS। এটি প্রতিটি image ও attachment সরাসরি MongoDB-তে সংরক্ষণ করে। পদ্ধতিটি সহজ। তবে মানুষ screenshot paste করতে থাকলে আপনার database এবং প্রতিটি mongodump-এর আকার সীমাহীনভাবে বাড়তে থাকবে। Admin → Settings → File Upload-এর অধীনে storage হিসেবে local filesystem অথবা S3-compatible bucket নির্বাচন করা যায়। সেখানে একটি যুক্তিসংগত maximum file size-ও নির্ধারণ করুন। আপনার team যদি মাঝেমধ্যে screenshot-এর বদলে সম্পূর্ণ photo library আদান-প্রদান করে, সেগুলো chat database-এ না রেখে dedicated photo server-এ সংরক্ষণ করা উচিত। PhotoPrism ও Immich-এর তুলনা-এ কোনটির RAM খরচ এবং প্রয়োজনীয় backup command কেমন, তা তুলনা করা হয়েছে। ছোট team-এর জন্য GridFS যথেষ্ট। তবে সময়ের সঙ্গে backup-এর আকার যে বাড়বে, তা মনে রাখুন।

mongodump দিয়ে ব্যাকআপ

আপনার সমস্ত ডেটা mongodb_data ভলিউমে থাকে। চলমান ডেটাবেস থেকে সরাসরি ভলিউম কপি করবেন না, বরং mongodump ব্যবহার করে একটি কনসিস্টেন্ট ডাম্প নিন এবং তা হোস্টের একটি ফাইলে স্ট্রিম করুন:

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

এই একটি gzipped আর্কাইভই আপনার সম্পূর্ণ ওয়ার্কস্পেস: ইউজার, চ্যানেল, মেসেজ, সেটিংস এবং আপনি যদি GridFS-এ আপলোড রেখে থাকেন, তবে সেই ফাইলগুলোও এর অন্তর্ভুক্ত। যদি আপনি আপলোডগুলোকে ফাইলসিস্টেম বা S3-তে সরিয়ে থাকেন, তবে সেই স্টোরটি আলাদাভাবে ব্যাকআপ নিন। নতুন স্ট্যাকে রিস্টোর করার জন্য প্রথমে replica set ইনিশিয়ালাইজ করুন, তারপর এটি চালান:

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

আর্কাইভটি সার্ভারের বাইরে কপি করুন—অবজেক্ট স্টোরেজ, অন্য কোনো সার্ভার বা এমন যেকোনো জায়গায় যেখানে VPS নষ্ট হয়ে গেলেও ব্যাকআপটি সুরক্ষিত থাকে। cron ব্যবহার করে প্রতি রাতে এই ডাম্প চালানোর ব্যবস্থা করুন। যে ব্যাকআপ আপনি কখনো রিস্টোর করে দেখেননি, তা কেবল একটি আশা, প্রকৃত ব্যাকআপ নয়। প্রয়োজনে ব্যবহারের আগে একবার একটি অস্থায়ী VPS-এ রিস্টোর প্রক্রিয়াটি অনুশীলন করে নিশ্চিত হোন যে এটি কাজ করছে।

আপগ্রেড: tag pin করুন, release note পড়ুন, MongoDB compatibility matrix মেনে চলুন

দুটি নিয়ম মানলে আপগ্রেডের কাজ সহজ থাকে। প্রথমত, Rocket.Chat একবারে একটি major version আপগ্রেড করুন। চালু হওয়ার সময় এটি schema migration চালায়। Rocket.Chat-এর আপগ্রেড নির্দেশিকায় বলা হয়েছে, major version-এর মধ্যে আপগ্রেড সবসময় ধারাবাহিকভাবে করতে হবে। সেখানে সতর্ক করা হয়েছে যে কোনো major version বাদ দিলে গুরুতর compatibility সমস্যা হতে পারে। সফটওয়্যার আপনাকে থামাবে বলে ধরে নেবেন না। এর documentation-এ এমন কোনো নিশ্চয়তা নেই যে 6.x থেকে সরাসরি 8.x-এ যাওয়া নিরাপদভাবে প্রত্যাখ্যান করা হবে। Migration মাঝপথে ব্যর্থ হলে lock সেট থেকে যায় এবং manual repair প্রয়োজন হয়। Image tag পরবর্তী major version-এর সর্বশেষ release-এ পরিবর্তন করুন। সেই release-এর breaking change-এর নোট পড়ুন। docker compose up -d চালান। এরপর পরবর্তী আপগ্রেডের আগে log monitor করে migration সম্পূর্ণ হয়েছে কি না দেখুন। দ্বিতীয়ত, MongoDB support matrix মেনে চলুন। প্রতিটি Rocket.Chat release নির্দিষ্ট কিছু MongoDB version সমর্থন করে। curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions আপনাকে জানায় কোন version সমর্থিত। MongoDB আপগ্রেড করার সময়, যেমন 7.0 থেকে 8.0-এ গেলে, একবারে একটি major version পার করুন এবং প্রতিটি ধাপের পরে feature-compatibility version সেট করুন। MongoDB 8.0-এ ওই command-এর জন্য স্পষ্টভাবে confirm: true প্রয়োজন। তা না হলে command ব্যর্থ হয়ে confirmation flag-সহ পুনরায় চালানোর নির্দেশ দেয়:

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

যেকোনো component আপগ্রেড করার আগে mongodump নিন। এটিই সম্পূর্ণ backup ব্যবস্থা।

ব্যর্থতার ধরন, নির্দিষ্ট string-সহ

docker compose up-এর পরপরই Rocket.Chat বারবার restart হয়, এবং docker compose logs rocketchat একটি MongoServerSelectionError দিয়ে পূর্ণ হয়। MongoDB চালু আছে, কিন্তু driver কোনো primary নির্বাচন করতে পারছে না। নির্দিষ্ট string-টি জানায় আপনি কোন ভুল করেছেন। Server selection timed out after 30000 ms-এ topology type ReplicaSetNoPrimary দেখা গেলে বুঝবেন আপনি কখনো rs.initiate() চালাননি; সেটে এখনো কোনো configuration নেই। getaddrinfo ENOTFOUND-এর পরে random hash দেখা গেলে বুঝবেন আপনি explicit host: "mongodb:27017" ছাড়া initiate করেছেন। ফলে MongoDB resolve করা যায় না এমন container hostname প্রকাশ করেছে। sudo docker compose exec mongodb mongosh --eval 'rs.status()' দিয়ে diagnosis করুন: এতে MongoServerError: no replset config has been received error দেখালে set-টি initiate করুন; কোনো member-এর name যদি random hash হয়, service name ব্যবহার করে আবার initiate করুন।

Web UI লোড হয়, কিন্তু login চিরকাল ঘুরতে থাকে এবং কখনো সম্পন্ন হয় না। Browser console খুললে WebSocket connection to 'wss://chat.example.com/websocket' failed দেখতে পাবেন। এটি প্রায় সবসময় ROOT_URL mismatch অথবা এমন proxy-এর কারণে হয়, যা upgrade header forward করছে না। ROOT_URL-এর মান https://-সহ exact 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-এর cache সীমিত করতে তার command-এ --wiredTigerCacheSizeGB সেট করুন। এটি default-এর চেয়ে কম রাখুন, বেশি নয়। উদাহরণস্বরূপ, 4 GB সার্ভারে 1 (default 1.5) অথবা 2 GB সার্ভারে 0.3 (default প্রায় 0.5) ব্যবহার করতে পারেন। তবে প্রকৃত load-এর অধীনে 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-সহ ব্যর্থ হয়। কোনো process ইতিমধ্যে port 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 প্রয়োজন?

হ্যাঁ, এমনকি একটি database node-সহ single server-এর ক্ষেত্রেও। Rocket.Chat MongoDB change stream ব্যবহার করে real time-এ message সরবরাহ করে, আর change stream শুধু replica set-এই কাজ করে; standalone mongod এটি খুলতে পারে না। একাধিক machine প্রয়োজন নেই; --replSet rs0 দিয়ে চালু করা একটি MongoDB container চালান এবং rs.initiate() দিয়ে one-member set initialize করুন। এই ধাপ বাদ দিলে driver কখনো primary খুঁজে পায় না। ফলে Rocket.Chat MongoServerSelectionError: Server selection timed out দেখিয়ে বারবার restart হয় এবং boot সম্পূর্ণ করে না।

self-hosted Rocket.Chat-এর কত RAM প্রয়োজন?

বাস্তব ব্যবহারের জন্য minimum 4 GB এবং ব্যস্ত team-এর জন্য 8 GB RAM রাখুন। Rocket.Chat-এর Node process প্রায় 1 থেকে 1.5 GB ব্যবহার করে। MongoDB-এর default WiredTiger cache-এর আকার হয় মোট RAM থেকে 1 GB বাদ দেওয়ার পর অবশিষ্টের অর্ধেক। এটি এমনভাবে নির্ধারিত হয় যেন server-এ আর কিছু চলছে না। 2 GB-এর server-এ ওই cache, Node-এর heap এবং mongod-এর নিজস্ব overhead একই RAM-এর জন্য প্রতিযোগিতা করে। বাস্তব load থাকলে out-of-memory killer mongod-কে বন্ধ করে দেয়, log-এ Killed দেখায় এবং exit code 137 ফেরত দেয়। 2 GB শুধু কয়েকজন test user নিয়ে software মূল্যায়নের জন্য যথেষ্ট।

Rocket.Chat-কে HTTPS-এর পেছনে কীভাবে রাখব?

একই VPS-এ একটি reverse proxy চালান। এটি TLS termination করবে এবং request 127.0.0.1:3000-এ forward করবে। Container-এর ROOT_URL-এ আপনার public https:// address সেট করুন। Proxy-কে WebSocket upgrade header forward করতে হবে। তা না হলে login আটকে থাকবে। Single-app setup-এর জন্য nginx-সহ Certbot সবচেয়ে সহজ। একটি proxy-এর পেছনে একাধিক container চালিয়ে automatic certificate management চাইলে Traefik বেশি সুবিধাজনক।

self-hosted Rocket.Chat-এর backup কীভাবে নেব?

Volume copy করার পরিবর্তে mongodump দিয়ে consistent database dump নিন: docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz। ওই archive-এ user, channel, message এবং setting থাকে। Storage GridFS-এ রেখে দিলে uploaded file-ও এতে অন্তর্ভুক্ত থাকে। Archive server-এর বাইরে copy করুন। cron দিয়ে nightly backup স্বয়ংক্রিয় করুন। এরপর একটি অস্থায়ী server-এ mongorestore অনুশীলন করুন, যাতে নিশ্চিত হতে পারেন যে restore সত্যিই কাজ করছে।

MongoDB নষ্ট না করে Rocket.Chat কীভাবে upgrade করব?

Rocket.Chat একবারে একটি major version upgrade করুন। Boot-এর সময় এটি migration চালায়। এর documentation সতর্ক করে যে major version বাদ দিলে গুরুতর compatibility সমস্যা হতে পারে; software আপনাকে থামাবে—এমন নিশ্চয়তা নেই। Pinned image tag পরিবর্তনের আগে প্রতিটি release-এর note পড়ুন। আপনার target release কোন MongoDB version সমর্থন করে, তা curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions দিয়ে পরীক্ষা করুন। MongoDB upgrade করার সময়ও একবারে একটি major version অতিক্রম করুন। প্রতিটি ধাপের পরে confirm: true দিয়ে setFeatureCompatibilityVersion সেট করুন। সবসময় প্রথমে একটি mongodump নিন।