SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

Docker ComposeでRocket.Chatを構築する方法

Docker ComposeでRocket.ChatをVPSに構築する手順を解説します。MongoDBのレプリカセット設定や、メモリ不足によるOOM Killerの発生を防ぐためのRAM計算、TLS設定、バックアップ方法まで、運用で躓きやすいポイントを網羅しました。

構築するもの

自分で完全に管理できるプライベートなチームチャットです。Docker Compose 上の自分の VPS で Rocket.Chat を実行し、TLS を終端し、すべてのメッセージをバックアップして移行できる MongoDB データベースに保存します。Rocket.Chat は、Slack や Teams に代わる成熟したオープンソースソフトウェアです。チャンネル、ダイレクトメッセージ、スレッド、ファイル共有、音声・ビデオ通話を、借りて管理するハードウェア上で利用できます。ただし、信頼できる選択肢は Rocket.Chat だけではありません。まだ選定中であれば、Mattermost、Rocket.Chat、Synapse、Zulip の比較で、後から問題になりやすい RAM、データベース、モバイルプッシュ、SSO、アップグレードを比較しています。アプリケーションは単一のコンテナで、数分で起動できます。実際に問題が発生する箇所は、ほとんどがその隣にあるデータベースです。そのため、このガイドの大部分では MongoDB を扱います。特に、初回に多くの人が驚く要件があります。Rocket.Chat はスタンドアロンの MongoDB では動作しません。「セット」が 1 ノードだけの場合でも、レプリカセットが必要です。

前提条件と、誰も教えてくれない RAM の計算

サーバーのサイズは現実的に見積もってください。小規模チームでの現実的な最低構成は、2 vCPU と 4 GB の RAM です。Rocket.Chat の Node.js プロセスだけで、およそ 1~1.5 GB を使用します。MongoDB の WiredTiger キャッシュは、デフォルトで「総 RAM から 1 GB を引いた値の 50%」と 0.256 GB の大きい方になります。このデフォルト値は、mongod がマシンを単独で使用することを前提にしています。総 RAM を基に算出され、Node がすでに使用しているメモリは考慮されません。そのため、4 GB のサーバーでは 1.5 GB、2 GB のサーバーでは約 0.5 GB になります。これに加えて、Node のヒープ、キャッシュ外で mongod 自体が使用するメモリ、オペレーティングシステムのメモリも必要です。2 GB の VPS では、起動直後は両方が収まっても、実際のトラフィックが発生するとすぐに競合します。MongoDB はキャッシュを拡大し、Node はヒープを拡大し、カーネルはページを使い果たします。そして out-of-memory killer が最も大きいプロセス(通常は mongod)を強制終了します。コンテナには Killed と表示され、Docker がコンテナを再起動します。その結果、本来なら問題なく処理できる負荷でも、数分おきに切断されるチャットサーバーになります。2 GB は 2 人で試すには十分ですが、チーム用サーバーには不十分です。まず 4 GB から始め、同時接続ユーザーが数十人、ビデオ通話、または増え続けるアップロード履歴を想定するなら 8 GB にしてください。サーバー上で動かす他のサービスに必要な容量も確保します。同じ VPS にNotion 風の AFFiNE ワークスペースを配置すると、さらに 4 つのコンテナが同じメモリページを取り合います。そのため、必要な RAM は Rocket.Chat 用の容量から差し引くのではなく、上乗せして確保する必要があります。

開始前に、さらに 3 つ用意する必要があります。1 つ目は、VPS のパブリック IP を指す A レコードを持つドメイン名です。Rocket.Chat のリアルタイム機能とモバイルクライアントには、IP アドレスではなく安定したホスト名が必要です。2 つ目は、サーバーのファイアウォールとプロバイダーのネットワークファイアウォールの両方で ポート 80 と 443 を開放することです。多くの管理パネルでは、プロバイダー側のネットワークファイアウォールは別の制御項目です。3 つ目は、root または sudo を利用できる、初期状態の Ubuntu 24.04 KVM VPS です。チャットサーバーを最初に運用するサービスにするかまだ検討中なら、2026 年にセルフホストする価値があるもののガイドでトレードオフを整理しています。

Docker エンジンと Compose プラグインをインストールする

Docker 独自の apt リポジトリを使用します。Ubuntu に付属する docker.io パッケージや、古いスタンドアロンの docker-compose Python バイナリは使用しません。現在の Compose は Docker プラグインであり、docker compose と入力して呼び出します。ハイフンは使わず、間にスペースを入れます。旧式の docker-compose v1 はサポートが終了しており、以下で使用する healthcheck と依存関係の構文を正しく処理できません。

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

両方が存在することを確認します。

sudo docker version
sudo docker compose version

docker compose version でバージョン行が表示されることを確認します。これが重要な確認項目です。現在のリリースでは Docker Compose version v5.x と表示されます(2026 年 10 月 2 日にリリースされた v5.6.0 が、2026-10-10 時点で最新でした)。古いインストールでは v2.x と表示される場合があります。Docker はどちらもサポートしています。Docker は、Compose v5 が機能面では v2 と同一であり、従来の v2 および v3 compose ファイル形式との混同を避けるために v5 と命名したと説明しています。そのため、このガイドではどちらを使用しても問題ありません。docker: 'compose' is not a docker command というエラーが表示される場合、プラグインはインストールされていません。このまま進むと後で原因の分かりにくい失敗が発生するため、ここで修正してください。

Compose ファイル: MongoDB を単一ノードのレプリカセットとして構成する

ここは誤りやすい部分なので、ゆっくり読んでください。Rocket.Chat は、接続中のクライアントへ新しいメッセージをリアルタイムで送信するために、MongoDB の change streams を使用します。change streams はレプリカセットでのみ利用できます。通常のスタンドアロン mongod を Rocket.Chat に指定すると、接続後に change stream の開始に失敗し、再起動ループを繰り返します。特別な構成は必要ありません。通常の MongoDB コンテナを 1 つ起動し、--replSet を指定してから、1 メンバーのセットを初期化します。

作業ディレクトリと 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 を渡し、レプリカセット名を明示します。MongoDB は、ドライバー間で一貫した動作を得るために、この設定を推奨しています。これを省略しても、それだけで問題が発生するわけではありません。directConnection の既定値は false なので、Rocket.Chat が解決できるホスト名でセットを初期化していれば、ドライバーはレプリカセットを検出し、プライマリへ操作を送信できます。次のセクションでこの初期化を行います。MONGO_OPLOG_URL は oplog が保存される local データベースを指定します。現在の Rocket.Chat は change streams を優先しますが、この設定を追加しても問題はなく、古いコードパスにも対応できます。depends_on は condition: service_healthy を使用します。そのため Compose は、MongoDB が ping に応答するまで Rocket.Chat を起動しません。これが healthcheck の役割です。

両方のイメージに実際のバージョンタグを固定してください。ここでは mongo:8.0 と、8.5.1 のような明示的な Rocket.Chat リリースを指定します。:latest は使用しないでください。これを使うと、無人運用の docker pull が、意図しないうえに移行もできないアップグレードになります。バージョンを固定する前に、現在の安定版 Rocket.Chat リリースと、対応している MongoDB のバージョンを確認してください。Rocket.Chat はリリースごとに機械可読な情報ドキュメントを公開しています。curl -s https://releases.rocket.chat/8.5.1/info | jq '{compatibleMongoVersions, lts}' は 8.5.1 について compatibleMongoVersions: ["8.0"] を返します。したがって、サポートされるエンジンは mongo:8.0 だけです。また、lts フラグによって、そのリリースが長期サポート版かどうかも確認できます。サーバーを頻繁に手入れしたくない場合は、長期サポート版を固定するとよいでしょう。すべてのプロジェクトがバージョン付きイメージを公開しているわけではありません。その場合は、ソース側でバージョンを固定します。openGym ワークアウトトラッカーをセルフホストする では、変更され続けるブランチを追跡するのではなく、特定の git タグをチェックアウトしてビルドします。

レプリカセットを初期化する

スタックを起動します。

sudo docker compose up -d

Rocket.Chat は直ちにクラッシュし、Docker は再起動を繰り返します。これは想定された動作です。まだレプリカセットが存在しないためです。次のコマンドを手動で 1 回実行して作成します。

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

正しい結果は { ok: 1 } です。数秒以内に単一ノードが自身を primary に選出します。次のコマンドで確認します。

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

PRIMARY が表示されることを確認します。このページ全体で最も重要なのは、host: "mongodb:27017" 引数です。メンバーリストを指定せずに単独の rs.initiate() を実行すると、MongoDB はコンテナ内部のホスト名、つまり a1b2c3d4e5f6 のようなランダムなハッシュをレプリカセットの接続先として通知します。自身のコンテナから接続する Rocket.Chat はその名前を解決できません。そのため MongoDB ドライバーはその名前の DNS 解決に失敗し、MongoServerSelectionError: getaddrinfo ENOTFOUND a1b2c3d4e5f6 をログに記録し続けて無限にループします。必ず MONGO_URL と一致する明示的なサービス名を指定して初期化してください。

初回起動: 起動を監視する

セットが primary になると、Rocket.Chat の次回の再起動で正常に接続し、初回起動時のマイグレーションが開始されます。ログを追跡します。

sudo docker compose logs -f rocketchat

待つべき行は、起動バナーです。

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

初回起動には時間がかかります。アプリケーションはデータベースのマイグレーションを実行し、インデックスを作成するため、心配する前に 1〜2 分待ってください。ログに ReplicaSetNoPrimary 型のトポロジー情報とともに MongoServerSelectionError: Server selection timed out after 30000 ms が繰り返し表示される場合、レプリカセットが初期化されていません。ランダムなハッシュに対して getaddrinfo ENOTFOUND が繰り返し表示される場合は、誤ったホストで初期化されています。どちらの場合も、1 つ前の手順に戻ってください。SERVER RUNNING が表示されたら、Rocket.Chat は 127.0.0.1:3000 で接続を待ち受けています。実際のホスト名と TLS を前段に設定する段階です。

TLS の背後に配置する

Rocket.Chat を平文の HTTP で公開しないでください。http:// 経由で一度ログインすると、経路上の誰にでも管理者パスワードを渡したことになります。同じホスト上のリバースプロキシで TLS を終端し、127.0.0.1:3000 に転送します。重要な点は 2 つあります。Rocket.Chat はリアルタイム通信を使用するため、プロキシは WebSocket のアップグレードヘッダーを転送する必要があります。これがないと通信が機能しません。また、コンテナの ROOT_URL は、ユーザーが入力する公開 HTTPS アドレスと完全に一致させる必要があります。

まず、アプリにプロキシし、アップグレードヘッダーを転送する平文 HTTP の nginx server block を作成します。/etc/nginx/sites-available/rocketchat として保存し、sites-enabled にシンボリックリンクを作成してから、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;
    }
}

今はポート 80 のままにしてください。listen 443 ssl; を含み、証明書のない block は sudo nginx -t にも合格しません。nginx を reload(sudo nginx -t && sudo systemctl reload nginx)してから、証明書を発行します。Ubuntu で最も簡単なのは Certbot と nginx による Let's Encrypt TLS 証明書 です。certbot --nginx は上記の block をその場で書き換え、listen 443 ssl;、ssl_certificate の行、自動的な 80 から 443 へのリダイレクトを追加し、更新も自動でスケジュールします。すでに 1 つのプロキシの背後で複数のコンテナを運用している場合は、複数の Docker アプリで TLS を自動化する Traefik のほうが整理しやすい方法です。rocketchat service に router と service の label を追加すると、nginx の block は不要で、Traefik が証明書の要求と更新を自動で行います。どちらの場合も、compose.yml の ROOT_URL を https://chat.example.com に設定し、sudo docker compose up -d を再実行して、コンテナに変更を反映させます。サーバーをパブリックインターネットではなく自分のネットワーク内からのみ到達可能にする場合は、VPS 上で自己ホストする WireGuard VPN を前段に置き、プロキシをトンネルのアドレスに bind します。

初回セットアップウィザード

https://chat.example.comにアクセスすると、Rocket.Chat の短いウィザードが始まります。最初に、admin accountとして氏名、ユーザー名、メールアドレス、強力なパスワードを設定します。存在するアカウントはこれだけなので、認証情報を失わないでください。次に、組織とサーバーの情報として、名前、業種、規模、サイト名、デフォルト言語を入力します。外観上の設定なので、入力して先に進みます。最後に、実際に重要な選択があります。このワークスペースを Rocket.Chat Cloud に登録するか、standaloneとして運用するかを選びます。

登録すると、Rocket.Chat のゲートウェイ経由のモバイルプッシュ通知とアドオンマーケットプレースを利用できます。ただし、Rocket.Chat のクラウドとのコントロールプレーン接続が必要になります。ゲートウェイ経由で送信するプッシュ通知は、ワークスペースの月間上限にも算入されます。standalone ではサーバーを完全にプライベートかつ依存関係なしで運用できますが、公式の iOS アプリと Android アプリではプッシュ通知を受信できなくなります。Rocket.Chat のドキュメントによると、これらのアプリは同社のクラウドゲートウェイでのみ動作し、ゲートウェイは未登録のワークスペースでは動作しないためです。この制約を回避するには、モバイルアプリを自社ブランドでビルドします。Push 設定でゲートウェイを無効にし、自分の APNs 証明書と Firebase Cloud Messaging の認証情報を入力して、ユーザーには公式アプリではなく自社アプリをインストールしてもらいます。プライバシーを最優先し、ユーザーが Web アプリを利用する場合、または自社のモバイルアプリを提供できる場合は standalone を選びます。公式アプリでのプッシュ通知が必須なら、登録を選びます。選択は後で Admin から変更できます。

参加者を招待する前にアクセスを制限する

Rocket.Chat はデフォルトで open registration が有効です。Registration Form は Public に設定されているため、URL を見つけた人は誰でもアカウントを作成できます。公開ホスト名でこの状態にすると、誰でも入れる状態になります。Admin → Settings → Accounts → Registration を開き、Registration Form を Disabled に設定します。これにより、アカウントを手動または招待リンクで作成できます。あるいは Secret URL に設定します。この画面で、特に公開読み取り専用チャンネルが必要でない限り、Allow Anonymous Read と Allow Anonymous Write も無効にします。すべてのアカウントを手動で作成するのが面倒で、チームがログインするサービスがこれだけでない場合は、Rocket.Chat の OAuth ログインを 自己ホストの Authentik SSO サーバー に接続します。これにより、参加者と離脱者の管理をアプリごとではなく、1 か所でまとめて処理できます。

アップロード先も決めておきます。デフォルトの File Upload ストレージは GridFS です。すべての画像と添付ファイルが MongoDB 内に保存されます。設定は簡単ですが、スクリーンショットを貼り付けるたびにデータベースと、取得するすべての mongodump が際限なく大きくなります。Admin → Settings → File Upload で、ストレージをローカルファイルシステムまたは S3 互換バケットに変更し、適切な最大ファイルサイズを設定できます。チームがたまにスクリーンショットを共有するのではなく、写真ライブラリ全体を交換する場合、それらはチャットデータベースではなく専用の写真サーバーに保存すべきです。PhotoPrism と Immich の比較では、それぞれに必要な RAM とバックアップコマンドを比較しています。小規模なチームなら GridFS で問題ありません。ただし、バックアップは時間とともに大きくなることを理解しておいてください。

mongodump によるバックアップ

すべてのデータは mongodb_data ボリュームに保存されています。稼働中のデータベースからボリュームを単純にコピーしないでください。mongodump を使用して整合性のあるダンプを取得し、ホスト上のファイルへストリームします。

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

この gzip 圧縮アーカイブだけで、ワークスペース全体を保存できます。ユーザー、チャンネル、メッセージ、設定に加え、アップロード先を GridFS のままにしている場合はファイルも含まれます。アップロード先をファイルシステムまたは S3 に移している場合は、そのストレージを別途バックアップしてください。新しいスタックへリストアする場合は、最初にレプリカセットを初期化してから、次を実行します。

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

アーカイブは ホストの外部、オブジェクトストレージ、別のサーバーなど、VPS の障害によってバックアップも失われない場所へコピーしてください。また、cron から毎晩ダンプを実行してください。一度もリストアしたことのないバックアップは、バックアップではなく期待にすぎません。必要になる前に、使い捨ての VPS で一度リストアを実行し、正常に動作することを確認してください。

アップグレード: タグを固定し、リリースノートを読み、MongoDB の対応表に従う

アップグレードを安全に進めるには、2つのルールを守ります。1つ目は、Rocket.Chat はメジャーバージョンを1つずつ上げることです。 起動時にスキーマ移行を実行します。Rocket.Chat のアップグレードドキュメントでも、メジャーバージョン間は必ず順番に更新するよう説明されており、メジャーバージョンを飛ばすと深刻な互換性問題が発生する可能性があると警告しています。ソフトウェアが処理を止めてくれるとは限りません。6.x から 8.x へ直接移行する操作を安全に拒否するとは、ドキュメントに記載されていません。移行が途中で失敗すると、ロックが残り、手動で修復する必要があります。イメージタグを次のメジャーバージョンの最新リリースに更新し、そのリリースのリリースノートで破壊的変更を確認し、docker compose up -d を実行します。次へ進む前に、ログを監視して移行が完了することを確認します。2つ目は、MongoDB の対応表に従うことです。 Rocket.Chat の各リリースは、特定の MongoDB バージョンに対応しています。curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions で対応バージョンを確認できます。MongoDB を更新する場合、たとえば 7.0 から 8.0 へ移行する場合も、メジャーバージョンを1つずつ上げ、各段階の後に feature-compatibility version を設定します。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は起動していますが、driverがprimaryを選択できていません。表示されたメッセージから、どの設定を誤ったかを特定できます。ReplicaSetNoPrimaryというトポロジータイプのServer selection timed out after 30000 msは、rs.initiate()をまだ実行しておらず、レプリカセットに設定がないことを示します。getaddrinfo ENOTFOUNDの後にランダムなhashが続く場合は、明示的なhost: "mongodb:27017"を指定せずに初期化したため、MongoDBが解決できないcontainer hostnameを通知しています。sudo docker compose exec mongodb mongosh --eval 'rs.status()'で診断します。MongoServerError: no replset config has been receivedというエラーが表示されたら、レプリカセットを初期化します。nameがランダムなhashのmemberが表示されたら、service nameを指定して再初期化します。

Web UIは読み込まれるが、ログイン処理が永遠に回り続けて完了しない。 ブラウザーのconsoleを開くと、WebSocket connection to 'wss://chat.example.com/websocket' failedが表示されます。ほとんどの場合、ROOT_URLの不一致、またはupgrade headersを転送していないproxyが原因です。ROOT_URLがhttps://を含む正確な公開アドレスと一致することを確認します。また、nginxのlocationブロックで、proxy_http_version 1.1を指定してUpgradeとConnection "upgrade"を設定していることを確認します。どちらかを変更した場合は、docker compose up -dを再実行します。

containerが停止を繰り返し、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を追加し、command内の--wiredTigerCacheSizeGBでMongoDBのcacheを制限します。デフォルト値より小さく設定してください。たとえば、4 GBのサーバーでは1(デフォルトは1.5)、2 GBのサーバーでは0.3(デフォルトは約0.5)にします。ただし、実際の負荷がかかると、swapは次のOOMを遅らせるだけです。

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

docker compose upがError response from daemon: driver failed programming external connectivity ... bind: address already in useで失敗する。 すでに別のプロセスがport 3000を使用しています。正常に停止しなかった以前のRocket.Chat containerや、別のアプリケーションが原因であることが多いです。sudo ss -ltnp | grep :3000で使用中のプロセスまたはcontainerを特定し、そのプロセスまたはcontainerを停止します。あるいは、mappingのhost側を127.0.0.1:3001:3000に変更し、proxyのproxy_passも同じ値に更新します。

FAQ

Rocket.Chat には本当に MongoDB のレプリカセットが必要ですか?

はい。データベースノードが 1 台だけの単一サーバーでも必要です。Rocket.Chat は MongoDB の change streams を使用してメッセージをリアルタイムで配信します。change streams はレプリカセット専用の機能であり、スタンドアロンの mongod では開けません。複数のマシンは必要ありません。--replSet rs0 で起動した MongoDB コンテナを 1 つだけ実行し、rs.initiate() で 1 メンバーのセットを初期化します。この手順を省くと、ドライバーは primary を見つけられません。そのため、Rocket.Chat は MongoServerSelectionError: Server selection timed out で再起動を繰り返し、起動を完了できません。

セルフホストの Rocket.Chat にはどの程度の RAM が必要ですか?

実用上の最小値として 4 GB、利用者の多いチームには 8 GB を見込んでください。Rocket.Chat の Node プロセスは約 1〜1.5 GB を使用します。MongoDB のデフォルトの WiredTiger cache は、他のプロセスが動作していない前提で、総 RAM から 1 GB を引いた値の半分に設定されます。2 GB のサーバーでは、この cache、Node の heap、mongod 自体のオーバーヘッドが競合します。実際の負荷がかかると out-of-memory killer が mongod を終了させ、ログに Killed と終了コード 137 が記録されます。2 GB で足りるのは、数人のテストユーザーでソフトウェアを評価する場合だけです。

Rocket.Chat を HTTPS の背後に配置するにはどうすればよいですか?

同じ VPS で TLS 終端を担うリバースプロキシを実行し、127.0.0.1:3000 へ転送します。コンテナの ROOT_URL には、公開されている https:// アドレスを設定します。プロキシでは WebSocket の upgrade ヘッダーを転送する必要があります。転送しないとログインがハングします。単一アプリの構成では、nginx と Certbot の組み合わせが最も簡単です。1 つのプロキシの背後で複数のコンテナを実行し、証明書管理を自動化したい場合は、Traefik のほうが構成を整理しやすくなります。

セルフホストの Rocket.Chat をバックアップするにはどうすればよいですか?

ボリュームをコピーするのではなく、mongodump で整合性のあるデータベースダンプを取得します。docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz。このアーカイブには、ユーザー、チャンネル、メッセージ、設定が含まれます。ストレージを GridFS にしたままの場合は、アップロードしたファイルも含まれます。アーカイブをサーバー外へコピーし、cron で毎晩自動実行してください。使い捨てのサーバーで mongorestore を実際に行い、リストアが機能することを確認してください。

MongoDB を壊さずに Rocket.Chat をアップグレードするにはどうすればよいですか?

Rocket.Chat はメジャーバージョンを 1 つずつ上げてください。起動時にマイグレーションを実行します。公式ドキュメントでは、メジャーバージョンを飛ばすと深刻な互換性問題が発生する可能性があると警告されています。アップグレードを阻止してくれるわけではありません。固定しているイメージタグを変更する前に、各リリースの変更履歴を確認してください。対象リリースがサポートする MongoDB のバージョンは curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions で確認します。MongoDB を更新する場合も、メジャーバージョンを 1 つずつ上げ、各段階の後に confirm: true で setFeatureCompatibilityVersion を設定してください。必ず最初に mongodump を取得してください。