SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

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

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

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

আপনার নিজস্ব মালিকানাধীন একটি প্রাইভেট টিম চ্যাট: Docker Compose-এর অধীনে আপনার নিজস্ব VPS-এ চলমান Rocket.Chat, যা TLS দ্বারা টার্মিনেট করা এবং প্রতিটি বার্তা একটি MongoDB ডেটাবেসে সংরক্ষিত থাকে যা আপনি ব্যাকআপ নিতে এবং স্থানান্তর করতে পারেন। Rocket.Chat হলো Slack এবং Teams-এর একটি পরিপক্ক ওপেন-সোর্স বিকল্প, যেখানে চ্যানেল, সরাসরি বার্তা, থ্রেড, ফাইল শেয়ারিং এবং ভয়েস ও ভিডিও কলের সুবিধা রয়েছে—সবই আপনার ভাড়া করা এবং নিয়ন্ত্রিত হার্ডওয়্যারে। অ্যাপ্লিকেশনটি একটি একক কন্টেইনার যা কয়েক মিনিটের মধ্যেই চালু হয়। সাধারণত যা কিছু সমস্যা হয় তা এর পাশের ডেটাবেসেই থাকে, তাই এই গাইডের বেশিরভাগ অংশই MongoDB নিয়ে, বিশেষ করে একটি প্রয়োজনীয়তা যা প্রথমবার ব্যবহারকারীদের অবাক করে: Rocket.Chat একটি standalone MongoDB-এর সাথে চলবে না। এর জন্য একটি replica set প্রয়োজন, এমনকি যদি সেই "সেট"-এ মাত্র একটি নোডও থাকে।

প্রয়োজনীয় শর্তাবলি এবং র‍্যামের হিসাব যা কেউ আপনাকে বলবে না

সার্ভারের আকার সততার সাথে নির্ধারণ করুন। একটি ছোট দলের জন্য বাস্তবসম্মত সর্বনিম্ন কনফিগারেশন হলো 2 vCPU এবং 4 GB RAM। Rocket.Chat-এর Node.js প্রসেসটির একাই প্রায় 1 থেকে 1.5 GB র‍্যাম প্রয়োজন হয় এবং MongoDB-এর WiredTiger ক্যাশ ডিফল্টভাবে অবশিষ্ট র‍্যামের প্রায় অর্ধেক দখল করে নেয়। 2 GB র‍্যামের VPS-এ বুট করার সময় দুটি প্রসেস চললেও, প্রকৃত ট্রাফিক আসার সাথে সাথেই তারা সংঘর্ষে লিপ্ত হয়: MongoDB তার ক্যাশ বাড়ায়, Node তার হিপ (heap) বাড়ায়, কার্নেলের মেমোরি ফুরিয়ে যায় এবং আউট-অফ-মেমোরি কিলার (OOM killer) সবচেয়ে বড় প্রসেসটিকে বন্ধ করে দেয়, যা সাধারণত mongod। কন্টেইনারটি Killed প্রিন্ট করে, Docker সেটিকে রিস্টার্ট করে এবং আপনি এমন একটি চ্যাট সার্ভার পাবেন যা সামান্য লোডেই বারবার বন্ধ হয়ে যায়। 2 GB র‍্যাম দুইজন ব্যবহারকারীর জন্য পরীক্ষা করার উপযোগী, কিন্তু এটি কোনো টিমের সার্ভার হতে পারে না। 4 GB র‍্যাম দিয়ে শুরু করুন এবং যদি কয়েক ডজন ব্যবহারকারী, ভিডিও কল বা ক্রমবর্ধমান আপলোড হিস্ট্রি প্রত্যাশা করেন, তবে 8 GB র‍্যাম ব্যবহার করুন।

শুরু করার আগে আপনার তিনটি বিষয় নিশ্চিত করতে হবে। একটি ডোমেইন নাম যার A record আপনার VPS-এর পাবলিক IP-কে নির্দেশ করে; Rocket.Chat-এর রিয়েল-টাইম ফিচার এবং মোবাইল ক্লায়েন্টগুলোর জন্য একটি স্থিতিশীল হোস্টনাম প্রয়োজন, শুধু IP ঠিকানা যথেষ্ট নয়। সার্ভার ফায়ারওয়াল এবং আপনার প্রোভাইডারের নেটওয়ার্ক ফায়ারওয়াল—যা বেশিরভাগ প্যানেলে আলাদাভাবে নিয়ন্ত্রণ করতে হয়—উভয়টিতেই 80 এবং 443 পোর্ট খোলা থাকতে হবে। এবং রুট বা sudo সুবিধা সহ একটি নতুন Ubuntu 24.04 KVM VPS প্রয়োজন। আপনি যদি এখনও সিদ্ধান্ত না নিয়ে থাকেন যে চ্যাট সার্ভার আপনার প্রথম সার্ভিস হিসেবে চালানো ঠিক হবে কি না, তবে 2026 সালে যা সেলফ-হোস্ট করা সার্থক তার নির্দেশিকা আপনাকে এর সুবিধা ও অসুবিধাগুলো বুঝতে সাহায্য করবে।

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

Ubuntu-এর ডিফল্ট docker.io প্যাকেজ বা পুরনো standalone docker-compose Python বাইনারি ব্যবহার না করে Docker-এর নিজস্ব apt repository ব্যবহার করুন। আধুনিক 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 v2.x-এর মতো আউটপুট পাওয়া যাচ্ছে কি না তা যাচাই করুন। যদি docker: 'compose' is not a docker command এরর দেখায়, তবে বুঝতে হবে plugin-টি ইনস্টল হয়নি। এটি ঠিক না করলে পরবর্তীতে বিভিন্ন জটিল সমস্যার সম্মুখীন হতে পারেন, তাই এখানেই সমাধান করুন।

Compose ফাইল: সিঙ্গেল-নোড রেপ্লিকা সেট হিসেবে MongoDB

এই অংশটি অনেকেই ভুল করেন, তাই মনোযোগ দিয়ে পড়ুন। Rocket.Chat রিয়েল-টাইমে সংযুক্ত ক্লায়েন্টদের কাছে নতুন মেসেজ পাঠানোর জন্য MongoDB change streams ব্যবহার করে, আর এই change streams শুধুমাত্র একটি রেপ্লিকা সেটেই কাজ করে। Rocket.Chat-কে সাধারণ standalone mongod-এর দিকে নির্দেশ করলে এটি সংযুক্ত হবে ঠিকই, কিন্তু change stream খুলতে ব্যর্থ হবে এবং বারবার রিস্টার্ট হতে থাকবে। এর সমাধান জটিল কিছু নয়: আপনি একটি সাধারণ MongoDB কন্টেইনারই চালাবেন, কিন্তু সেটিকে --replSet ফ্ল্যাগ দিয়ে শুরু করবেন এবং তারপর একটি এক-সদস্যের সেট ইনিশিয়ালাইজ করবেন।

একটি ওয়ার্কিং ডিরেক্টরি এবং একটি 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 নেই, তাই শুধুমাত্র একই মেশিনে থাকা রিভার্স প্রক্সি দিয়েই এটি অ্যাক্সেস করা উচিত। এটিকে সব ইন্টারফেসে বাইন্ড করলে একটি প্লেইনটেক্সট লগইন পেজ সরাসরি পাবলিক ইন্টারনেটে উন্মুক্ত হয়ে যাবে। MongoDB হোস্টের জন্য মোটেও পাবলিশ করা হয়নি; এটি শুধুমাত্র Compose-এর অভ্যন্তরীণ নেটওয়ার্কে mongodb নামে অ্যাক্সেসযোগ্য, যা ঠিক সেই হোস্টনাম যা MONGO_URL ব্যবহার করে। MONGO_URL-এ ?replicaSet=rs0 অন্তর্ভুক্ত থাকে, এটি বাদ দিলে ড্রাইভার সার্ভারটিকে standalone হিসেবে গণ্য করবে, যদিও এটি একটি রেপ্লিকা সেট, ফলে change streams কাজ করবে না। MONGO_OPLOG_URL সেই local ডাটাবেসকে নির্দেশ করে যেখানে oplog থাকে; আধুনিক Rocket.Chat change streams পছন্দ করে, তবে এটি সেট করে রাখা ক্ষতিকর নয় এবং পুরনো কোড পাথগুলোকে সচল রাখে। depends_on-এ condition: service_healthy ব্যবহার করা হয়েছে, তাই MongoDB একটি ping-এর উত্তর না দেওয়া পর্যন্ত Compose Rocket.Chat শুরু করবে না, হেলথচেকের উদ্দেশ্য এটাই।

উভয় image-এ নির্দিষ্ট version tag ব্যবহার করুন: mongo:8.0 এবং একটি স্পষ্ট Rocket.Chat release, যেমন এখানে 8.5.1। কখনো :latest ব্যবহার করবেন না। এটি unattended docker pull-কে অনিচ্ছাকৃত এবং migration করা যায় না এমন upgrade-এ পরিণত করে। Pin করার আগে বর্তমান stable Rocket.Chat release এবং এটি সমর্থন করে এমন MongoDB version পরীক্ষা করুন। Rocket.Chat প্রতিটি release-এর জন্য machine-readable তথ্যের 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-ও থাকে, যা জানায় release-টি long-term-support build কি না। যে server নিয়মিত দেখভাল করতে চান না, তার জন্য এমন build pin করা উপযোগী।

সব project versioned image প্রকাশ করে না। সে ক্ষেত্রে pin source-এ করতে হয়। self-hosting করা openGym workout tracker-এর ক্ষেত্রে নির্দিষ্ট 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 করুন।

প্রথমবার সেটআপ উইজার্ড

https://chat.example.com-এ ব্রাউজ করুন এবং Rocket.Chat আপনাকে একটি সংক্ষিপ্ত উইজার্ডের মাধ্যমে নির্দেশনা দেবে। প্রথমে, admin account, একটি আসল নাম, ইউজারনেম, ইমেইল এবং একটি শক্তিশালী পাসওয়ার্ড সেট করুন; এটিই একমাত্র বিদ্যমান অ্যাকাউন্ট, তাই এটি হারাবেন না। এরপর, organisation and server info, যেমন নাম, ইন্ডাস্ট্রি, আকার, সাইট-এর নাম এবং ডিফল্ট ভাষা দিন; এগুলো মূলত আনুষ্ঠানিক তথ্য, পূরণ করে এগিয়ে যান। এরপর সবচেয়ে গুরুত্বপূর্ণ সিদ্ধান্তটি নিন: register this workspace অপশনটি ব্যবহার করে Rocket.Chat Cloud-এর সাথে যুক্ত হবেন, নাকি এটিকে standalone হিসেবে রাখবেন।

রেজিস্ট্রেশন করলে Rocket.Chat-এর গেটওয়ের মাধ্যমে মোবাইল পুশ নোটিফিকেশন এবং অ্যাড-অন মার্কেটপ্লেস ব্যবহারের সুবিধা পাওয়া যায়, তবে এর বিনিময়ে Rocket.Chat ক্লাউডের সাথে একটি কন্ট্রোল-প্লেন সম্পর্ক তৈরি হয়। Standalone মোড সার্ভারকে সম্পূর্ণ ব্যক্তিগত এবং নির্ভরশীলতামুক্ত রাখে, কিন্তু এতে iOS এবং Android পুশ নোটিফিকেশন কাজ করা বন্ধ করে দেয়। কারণ Apple এবং Google কোনো স্ব-নির্মিত অ্যাপকে পুশ সার্টিফিকেট ব্যবহারের অনুমতি দেয় না; অফিসিয়াল অ্যাপগুলো ক্লাউড গেটওয়ের মাধ্যমে কাজ করে। যদি গোপনীয়তাই আপনার মূল লক্ষ্য হয় এবং ব্যবহারকারীরা ওয়েব অ্যাপ ব্যবহার করেন, তবে standalone বেছে নিন; আর যদি মোবাইল পুশ নোটিফিকেশন অপরিহার্য হয়, তবে রেজিস্ট্রেশন বেছে নিন। আপনি পরবর্তীতে Admin সেকশন থেকে আপনার সিদ্ধান্ত পরিবর্তন করতে পারবেন।

কাউকে আমন্ত্রণ জানানোর আগে সার্ভার সুরক্ষিত করুন

Rocket.Chat ডিফল্টভাবে open registration on অবস্থায় থাকে, অর্থাৎ Registration Form-এর সেটিং Public করা থাকে। ফলে যে কেউ URL খুঁজে পেলে অ্যাকাউন্ট তৈরি করতে পারে। একটি পাবলিক হোস্টনামের ক্ষেত্রে এটি একটি উন্মুক্ত দরজার মতো। Admin → Settings → Accounts → Registration-এ যান এবং Registration Form-কে Disabled করুন, যাতে আপনি নিজে অ্যাকাউন্ট তৈরি করতে পারেন বা ইনভাইট লিংকের মাধ্যমে তা করতে পারেন, অথবা এটিকে Secret URL করে দিন। একই সাথে, যদি না আপনি বিশেষভাবে কোনো পাবলিক রিড-অনলি চ্যানেল চান, তবে Allow Anonymous Read এবং Allow Anonymous Write বন্ধ করে দিন। যদি প্রতিটি অ্যাকাউন্ট হাতে তৈরি করা ক্লান্তিকর মনে হয় এবং এটিই একমাত্র সার্ভিস না হয় যেখানে আপনার টিম লগইন করে, তবে Rocket.Chat-এর OAuth লগইনকে একটি self-hosted Authentik SSO server-এর দিকে নির্দেশ করুন। এতে নতুন সদস্য যোগ করা বা বাদ দেওয়ার কাজগুলো প্রতিটি অ্যাপের জন্য আলাদাভাবে না করে এক জায়গা থেকেই নিয়ন্ত্রণ করা সম্ভব হবে।

ফাইল আপলোড কোথায় জমা হবে সেটিও নির্ধারণ করুন। ডিফল্ট File Upload স্টোরেজ হলো GridFS, যা প্রতিটি ছবি এবং অ্যাটাচমেন্ট সরাসরি MongoDB-এর ভেতরে জমা করে। এটি সহজ হলেও এর মানে হলো আপনার ডাটাবেস এবং প্রতিটি mongodump-এর আকার বাড়তে থাকবে, কারণ ব্যবহারকারীরা নিয়মিত স্ক্রিনশট শেয়ার করবে। Admin → Settings → File Upload-এর অধীনে আপনি স্টোরেজ পরিবর্তন করে লোকাল ফাইলসিস্টেম বা S3-compatible বাকেটে নিতে পারেন এবং ফাইলের একটি যৌক্তিক সর্বোচ্চ আকার নির্ধারণ করে দিতে পারেন। ছোট টিমের জন্য GridFS ঠিক আছে; শুধু মনে রাখবেন যে সময়ের সাথে সাথে আপনার ব্যাকআপের আকার বড় হতে থাকবে।

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-এ রিস্টোর প্রক্রিয়াটি অনুশীলন করে নিশ্চিত হোন যে এটি কাজ করছে।

আপগ্রেড: ট্যাগ পিন করা, নোট পড়া এবং MongoDB ম্যাট্রিক্স মেনে চলা

আপগ্রেড প্রক্রিয়াকে ঝামেলামুক্ত রাখতে দুটি নিয়ম মেনে চলুন। প্রথমত, Rocket.Chat-এর একটি করে মেজর ভার্সন আপগ্রেড করুন। এটি বুট হওয়ার সময় স্কিমা মাইগ্রেশন চালায় এবং সরাসরি বড় লাফ দেওয়া থেকে বিরত থাকে; 6.x থেকে সরাসরি 8.x-এ যাওয়ার চেষ্টা করলে এটি ডেটা নষ্ট না করে মাইগ্রেশন এরর দিয়ে আটকে যাবে। ইমেজ ট্যাগটিকে পরবর্তী মেজর ভার্সনের লেটেস্ট রিলিজে পরিবর্তন করুন, ব্রেকিং পরিবর্তনের জন্য সেই রিলিজের নোটগুলো পড়ুন, docker compose up -d চালান এবং পরবর্তী ধাপে যাওয়ার আগে লগগুলো মাইগ্রেশন শেষ হওয়া পর্যন্ত পর্যবেক্ষণ করুন। দ্বিতীয়ত, MongoDB সাপোর্ট ম্যাট্রিক্স মেনে চলুন। প্রতিটি Rocket.Chat রিলিজ নির্দিষ্ট কিছু MongoDB ভার্সন সাপোর্ট করে এবং curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions আপনাকে জানাবে কোনটি সমর্থিত। যখন আপনি MongoDB আপগ্রেড করবেন, যেমন 7.0 থেকে 8.0, তখন একটি করে মেজর ভার্সন পরিবর্তন করুন এবং প্রতিটি ধাপের পর feature-compatibility ভার্সন সেট করুন। MongoDB 8.0-তে এই কমান্ডটির জন্য একটি স্পষ্ট confirm: true প্রয়োজন, অন্যথায় এটি একটি কনফার্মেশন ফ্ল্যাগসহ পুনরায় চালানোর বার্তা দিয়ে কাজ করা বন্ধ রাখবে:

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

প্রতিটি কম্পোনেন্ট আপগ্রেড করার আগে একটি mongodump নিন। এটিই আপনার সম্পূর্ণ বীমা পলিসি।

ব্যর্থতার ধরন এবং সঠিক স্ট্রিং

docker compose up-এর ঠিক পরেই Rocket.Chat রিস্টার্ট-লুপে আটকে যায় এবং docker compose logs rocketchat একটি MongoServerSelectionError দিয়ে পূর্ণ হয়ে যায়। MongoDB চলছে কিন্তু ড্রাইভার প্রাইমারি নির্বাচন করতে পারছে না, এবং সঠিক স্ট্রিংটি আপনাকে বলে দেবে আপনি কী ভুল করেছেন। Server selection timed out after 30000 ms এবং এর টপোলজি টাইপ 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 এরর দেয়, তবে সেটটি ইনিশিয়েট করুন; যদি এটি এমন কোনো মেম্বার দেখায় যার name একটি র‍্যান্ডম হ্যাশ, তবে সার্ভিস নেম ব্যবহার করে পুনরায় ইনিশিয়েট করুন।

ওয়েব UI লোড হয় কিন্তু লগইন প্রসেস চিরকাল ঘুরতে থাকে এবং কখনোই সম্পন্ন হয় না। ব্রাউজার কনসোল খুলুন এবং আপনি WebSocket connection to 'wss://chat.example.com/websocket' failed দেখতে পাবেন। এটি প্রায় সবসময়ই একটি ROOT_URL অমিল বা এমন কোনো প্রক্সির কারণে হয় যা upgrade হেডারগুলো ফরওয়ার্ড করছে না। নিশ্চিত করুন যে ROOT_URL এর মান https:// সহ সঠিক পাবলিক অ্যাড্রেসের সমান এবং আপনার nginx location ব্লকটি Upgrade এবং Connection "upgrade" কে proxy_http_version 1.1 দিয়ে সেট করেছে। যেকোনো একটি পরিবর্তন করুন এবং পুনরায় docker compose up -d চালান।

একটি কন্টেইনার বারবার বন্ধ হয়ে যাচ্ছে এবং docker compose ps দেখাচ্ছে যে এটি Restarting docker compose logs মাঝপথে কেটে যাচ্ছে এবং sudo dmesg | tail-এ oom-killer থেকে Out of memory: Killed process 12345 (mongod) দেখাচ্ছে; এক্সিট কোডটি হলো 137। সার্ভারে RAM শেষ হয়ে গেছে। এর প্রকৃত সমাধান হলো একটি বড় VPS, কমপক্ষে 4 GB। সাময়িক সমাধান হিসেবে swap যোগ করুন এবং MongoDB-এর ক্যাশকে এর command-এ --wiredTigerCacheSizeGB 1 দিয়ে সীমাবদ্ধ করুন, তবে 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 ব্যবহার করে, আর change streams শুধুমাত্র replica set-এই কাজ করে; একটি standalone mongod এটি ওপেন করতে পারে না। এর জন্য একাধিক মেশিনের প্রয়োজন নেই; আপনি --replSet rs0 দিয়ে একটি MongoDB কন্টেইনার চালু করতে পারেন এবং rs.initiate() ব্যবহার করে একটি মেম্বারবিশিষ্ট সেট ইনিশিয়ালাইজ করতে পারেন। এই ধাপটি বাদ দিলে ড্রাইভার কখনোই primary খুঁজে পাবে না, ফলে Rocket.Chat MongoServerSelectionError: Server selection timed out এর সাথে রিস্টার্ট-লুপে আটকে যাবে এবং কখনোই বুট সম্পন্ন করতে পারবে না।

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

ব্যবহারিক সর্বনিম্ন হিসেবে 4 GB এবং ব্যস্ত টিমের জন্য 8 GB RAM পরিকল্পনা করুন। Rocket.Chat-এর Node প্রসেস প্রায় 1 থেকে 1.5 GB RAM ব্যবহার করে এবং MongoDB তার WiredTiger ক্যাশের জন্য অবশিষ্ট RAM-এর প্রায় অর্ধেক দাবি করে। তাই 2 GB-এর বক্সে এই দুটির মধ্যে সংঘর্ষ হয় এবং কোনো বাস্তব লোড থাকলে out-of-memory killer mongod কে বন্ধ করে দেয়, যা লগে Killed এবং exit code 137 হিসেবে দেখা যায়। 2 GB RAM শুধুমাত্র কয়েকজন টেস্ট ইউজার নিয়ে সফটওয়্যারটি যাচাই করার জন্য যথেষ্ট।

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

একই VPS-এ একটি reverse proxy চালান যা TLS termination করবে এবং 127.0.0.1:3000-এ ফরোয়ার্ড করবে, এবং কন্টেইনারের ROOT_URL-কে আপনার পাবলিক https:// ঠিকানায় সেট করুন। প্রক্সিকে অবশ্যই WebSocket upgrade হেডারগুলো ফরোয়ার্ড করতে হবে, অন্যথায় লগইন প্রক্রিয়া আটকে যাবে। nginx-এর সাথে Certbot ব্যবহার করা একক অ্যাপের জন্য সবচেয়ে সহজ সেটআপ; যদি আপনি একটি প্রক্সির পেছনে একাধিক কন্টেইনার চালান এবং স্বয়ংক্রিয় সার্টিফিকেট ম্যানেজমেন্ট চান, তবে Traefik ব্যবহার করা বেশি সুবিধাজনক।

আমি কীভাবে self-hosted Rocket.Chat-এর ব্যাকআপ নেব?

ভলিউম কপি না করে mongodump ব্যবহার করে একটি consistent ডাটাবেস ডাম্প নিন: docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz। এই আর্কাইভে ইউজার, চ্যানেল, মেসেজ এবং সেটিংস থাকে, সেইসাথে যদি আপনি স্টোরেজ GridFS-এ রেখে থাকেন তবে আপলোড করা ফাইলগুলোও থাকে। এটি সার্ভার থেকে কপি করে নিন, cron ব্যবহার করে প্রতি রাতে স্বয়ংক্রিয় করুন এবং একটি অস্থায়ী বক্সে mongorestore অনুশীলন করুন যাতে আপনি নিশ্চিত হতে পারেন যে রিস্টোর প্রক্রিয়াটি সঠিকভাবে কাজ করছে।

MongoDB নষ্ট না করে আমি কীভাবে Rocket.Chat আপগ্রেড করব?

Rocket.Chat একবারে একটি করে মেজর ভার্সন আপগ্রেড করুন; এটি বুট হওয়ার সময় মাইগ্রেশন চালায় এবং মেজর ভার্সন বাদ দিয়ে আপগ্রেড করতে দেয় না। pinned image tag পরিবর্তন করার আগে প্রতিটি রিলিজের নোট পড়ুন। curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions ব্যবহার করে চেক করুন আপনার টার্গেট রিলিজ কোন MongoDB ভার্সন সাপোর্ট করে। MongoDB আপগ্রেড করার সময় একবারে একটি মেজর ভার্সন পরিবর্তন করুন এবং প্রতিটি ধাপের পর confirm: true দিয়ে setFeatureCompatibilityVersion সেট করুন। সবসময় আগে একটি mongodump নিয়ে রাখুন।