SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Установка Rocket.Chat через Docker Compose на VPS

Разверните Rocket.Chat на собственном сервере с использованием Docker Compose. Узнайте, как настроить обязательный replica set для MongoDB, TLS и резервное копирование данных.

Что вы создаете

Частный командный чат, который полностью принадлежит вам: Rocket.Chat, работающий на вашем собственном VPS через Docker Compose с TLS-терминацией, где все сообщения хранятся в базе данных MongoDB, которую можно копировать и переносить. Rocket.Chat — это зрелая open-source альтернатива Slack и Teams, поддерживающая каналы, личные сообщения, ветки обсуждений, обмен файлами, а также голосовую и видеосвязь на оборудовании, которое вы арендуете и контролируете. Это не единственный достойный вариант; если вы все еще выбираете, сравнение Mattermost, Rocket.Chat, Synapse и Zulip поможет сопоставить их по критическим параметрам: потреблению RAM, базе данных, push-уведомлениям для мобильных устройств, SSO и обновлениям. Приложение представляет собой единый контейнер, который запускается за считанные минуты. Все потенциальные проблемы связаны с базой данных, поэтому большая часть этого руководства посвящена MongoDB и одному требованию, которое часто становится неожиданностью: Rocket.Chat не работает с автономным (standalone) экземпляром MongoDB. Ему необходим набор реплик (replica set), даже если этот «набор» состоит из одного узла.

Предварительные требования и расчет оперативной памяти, о котором обычно молчат

Реалистично оценивайте ресурсы сервера. Минимально допустимый порог для небольшой команды — 2 vCPU и 4 ГБ оперативной памяти. Процесс Node.js для Rocket.Chat потребляет примерно от 1 до 1.5 ГБ, а кэш WiredTiger в MongoDB по умолчанию занимает либо 50% от (общего объема RAM минус 1 ГБ), либо 0.256 ГБ, в зависимости от того, что больше. Этот расчет по умолчанию предполагает, что mongod является единственным потребителем ресурсов: он вычисляется исходя из общего объема RAM и не учитывает память, уже занятую Node. В результате на сервере с 4 ГБ RAM кэш составит 1.5 ГБ, а на сервере с 2 ГБ — около 0.5 ГБ. Это происходит сверх объема кучи Node, памяти mongod вне кэша и ресурсов операционной системы. На VPS с 2 ГБ оба процесса запускаются успешно, но при появлении реальной нагрузки начинают конфликтовать: MongoDB расширяет кэш, Node увеличивает кучу, ядро исчерпывает свободные страницы памяти, и OOM-killer завершает самый ресурсоемкий процесс, которым обычно оказывается mongod. Контейнер выводит Killed, Docker перезапускает его, и в итоге чат-сервер падает каждые несколько минут под нагрузкой, которую должен был легко выдерживать. 2 ГБ достаточно для ознакомления с участием двух человек, но это не сервер для полноценной команды. Начинайте с 4 ГБ, а если ожидаете десятки одновременных пользователей, видеозвонки или растущую историю загрузок — выделяйте 8 ГБ. Учитывайте и другие задачи сервера: размещение рабочего пространства AFFiNE в стиле Notion на том же VPS добавит еще четыре контейнера, конкурирующих за те же страницы памяти, поэтому их RAM должна быть добавлена к требованиям Rocket.Chat, а не выделена из них.

Перед началом работы необходимо подготовить три вещи. Доменное имя с A-записью, указывающей на публичный IP-адрес вашего VPS: функции реального времени и мобильные клиенты Rocket.Chat требуют стабильного имени хоста, а не прямого IP. Открытые порты 80 и 443 как в локальном брандмауэре сервера, так и в сетевом брандмауэре провайдера (последний обычно настраивается в панели управления). И чистая установка Ubuntu 24.04 на KVM VPS с доступом root или sudo. Если вы еще не решили, стоит ли начинать с чат-сервера, руководство по тому, что стоит хостить самостоятельно в 2026 году, поможет оценить все за и против.

Установка Docker engine и плагина Compose

Используйте официальный apt-репозиторий Docker, а не пакет docker.io, который поставляется в Ubuntu, и не устаревший автономный Python-бинарный файл docker-compose. Современный 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 (версия v5.6.0, выпущенная 2 октября 2026 года, была актуальной на 2026-10-10); более старые установки могут выводить v2.x, Docker поддерживает оба варианта. Docker описывает Compose v5 как функционально идентичный v2; нумерация v5 введена, чтобы избежать путаницы с устаревшими форматами файлов compose v2 и v3, поэтому для данного руководства подходит любой из них. Если возникает ошибка docker: 'compose' is not a docker command, значит, плагин не установлен, и в дальнейшем вы столкнетесь с непонятными сбоями — устраните проблему на этом этапе.

Файл compose: MongoDB как реплика-сет из одного узла

Это тот момент, в котором часто ошибаются, поэтому читайте внимательно. Rocket.Chat использует change streams в MongoDB для отправки новых сообщений подключенным клиентам в реальном времени, а 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, поэтому доступ к нему должен быть только у reverse proxy на том же хосте. Привязка к любому интерфейсу выставила бы страницу входа в открытом виде прямо в публичный интернет. MongoDB вообще не публикуется на хост; она доступна только через внутреннюю сеть Compose по имени mongodb, которое в точности совпадает с именем хоста, используемым MONGO_URL. MONGO_URL содержит ?replicaSet=rs0, где имя сета задается явно; MongoDB рекомендует указывать его для согласованного поведения драйверов. Если его не указать, это само по себе ничего не сломает: directConnection по умолчанию использует false, поэтому драйвер все равно обнаружит реплика-сет и направит операции на primary, при условии, что сет был инициализирован с именем хоста, которое Rocket.Chat может разрешить (об этом в следующем разделе). MONGO_OPLOG_URL указывает на базу данных local, где хранится oplog; современный Rocket.Chat предпочитает change streams, но установка этого параметра безопасна и поддерживает работу старых путей кода. depends_on использует condition: service_healthy, поэтому Compose дождется ответа MongoDB на ping, прежде чем запускать Rocket.Chat — именно для этого нужен healthcheck.

Фиксируйте реальные версии тегов для обоих образов, например mongo:8.0 и конкретный релиз Rocket.Chat, такой как 8.5.1, и никогда не используйте :latest, который превращает автоматическое обновление docker pull в случайный апгрейд, который невозможно откатить. Перед фиксацией версий проверьте текущий стабильный релиз Rocket.Chat и поддерживаемые им версии MongoDB. Rocket.Chat публикует машиночитаемый документ с информацией по каждому релизу: curl -s https://releases.rocket.chat/8.5.1/info | jq '{compatibleMongoVersions, lts}' возвращает compatibleMongoVersions: ["8.0"] для версии 8.5.1, поэтому mongo:8.0 является единственным поддерживаемым движком, плюс флаг lts, который сообщает, является ли этот релиз версией с долгосрочной поддержкой (LTS), которую стоит фиксировать для сервера, не требующего постоянного присмотра. Не каждый проект публикует версионированные образы; в таком случае фиксация переносится на исходный код: self-hosting the openGym workout tracker означает использование конкретного git-тега и сборку из него, вместо следования за постоянно меняющейся веткой.

Инициализация набора реплик

Запустите стек:

sudo docker compose up -d

Rocket.Chat сразу начнет аварийно завершаться, а Docker будет постоянно перезапускать его. Это ожидаемое поведение, так как набор реплик еще не создан. Создайте его вручную один раз:

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.

Первый запуск: отслеживание процесса

Как только набор реплик становится основным, следующий перезапуск 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 по незашифрованному HTTP. Если вы один раз войдёте в систему через http://, ваш пароль администратора станет доступен любому, кто находится на пути следования трафика. Выполняйте TLS termination на reverse proxy, установленном на том же сервере, и перенаправляйте запросы на 127.0.0.1:3000. Важны два момента: прокси должен передавать заголовки WebSocket upgrade, так как Rocket.Chat работает в режиме реального времени и без них перестанет функционировать, а ROOT_URL контейнера должен в точности совпадать с публичным HTTPS-адресом, который вводят пользователи.

Начните с простого блока сервера nginx для HTTP, который проксирует запросы к приложению и передаёт заголовки upgrade. Сохраните его в /etc/nginx/sites-available/rocketchat, создайте символическую ссылку в sites-enabled и перезагрузите конфигурацию:

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; без сертификата не пройдёт проверку sudo nginx -t. Перезагрузите nginx (sudo nginx -t && sudo systemctl reload nginx), а затем выпустите сертификат. Самый простой путь в Ubuntu — получение TLS-сертификатов Let's Encrypt с помощью Certbot и nginx: certbot --nginx автоматически перепишет указанный выше блок, добавив listen 443 ssl;, строки ssl_certificate и настроив автоматическое перенаправление с 80 на 443 порт, а также запланирует обновление сертификатов. Если вы уже используете несколько контейнеров за одним прокси, более аккуратным вариантом будет Traefik с автоматическим TLS для множества Docker-приложений: добавьте метки router и service к сервису rocketchat, и Traefik сам запросит и обновит сертификат без необходимости создавать блоки в nginx. В любом случае установите ROOT_URL в значение https://chat.example.com в файле compose.yml и перезапустите sudo docker compose up -d, чтобы контейнер применил изменения. Если вы хотите, чтобы сервер был доступен только из вашей внутренней сети, а не из публичного Интернета, установите перед ним собственный VPN-шлюз WireGuard на VPS и привяжите прокси к адресу внутри туннеля.

Мастер первоначальной настройки

Перейдите по адресу https://chat.example.com, и Rocket.Chat предложит пройти короткий мастер настройки. Сначала создается учетная запись администратора: укажите реальное имя, имя пользователя, адрес электронной почты и надежный пароль. Это единственная существующая учетная запись, поэтому не потеряйте данные для входа. Затем заполните информацию об организации и сервере: название, отрасль, размер компании, имя сайта и язык по умолчанию. Эти данные носят справочный характер, заполните их и переходите далее. После этого следует выбор, который действительно важен: зарегистрировать рабочее пространство в Rocket.Chat Cloud или оставить его в режиме standalone (автономном).

Регистрация позволяет использовать push-уведомления для мобильных устройств через шлюз Rocket.Chat и открывает доступ к магазину дополнений. Обратной стороной является зависимость от облачной инфраструктуры Rocket.Chat; уведомления, отправленные через шлюз, учитываются в ежемесячном лимите вашего рабочего пространства. Режим standalone обеспечивает полную приватность и независимость сервера, но официальные приложения для iOS и Android перестают получать push-уведомления. Согласно документации Rocket.Chat, эти приложения работают только через облачный шлюз, который не функционирует на незарегистрированных серверах. Решением этой проблемы является создание собственной брендированной сборки мобильного приложения: отключите шлюз в настройках Push, вставьте собственные сертификаты APNs и учетные данные Firebase Cloud Messaging, а затем предложите пользователям установить ваше приложение вместо официального. Выбирайте режим standalone, если приватность является приоритетом, пользователи работают преимущественно через веб-интерфейс или вы готовы заниматься распространением собственного мобильного приложения. Выбирайте регистрацию, если работа push-уведомлений в официальных приложениях обязательна. Вы сможете изменить это решение позже в разделе Admin.

Ограничьте доступ перед тем, как приглашать пользователей

Rocket.Chat поставляется с включенной открытой регистрацией по умолчанию: форма регистрации установлена в Public, поэтому любой, кто найдет URL, сможет создать учетную запись. Для публичного хоста это означает открытую дверь. Перейдите в Admin → Settings → Accounts → Registration и установите для Registration Form значение Disabled, чтобы создавать учетные записи вручную или по ссылке-приглашению, либо Secret URL. Находясь там же, отключите Allow Anonymous Read и Allow Anonymous Write, если вам не нужен публичный канал только для чтения. Если ручное создание каждой учетной записи кажется утомительным, а это не единственный сервис, которым пользуется ваша команда, настройте OAuth-авторизацию Rocket.Chat через собственный сервер Authentik SSO. Так вы будете управлять доступом новых и уходящих сотрудников централизованно, а не для каждого приложения отдельно.

Также определитесь с местом хранения загружаемых файлов. По умолчанию для File Upload используется хранилище GridFS, которое сохраняет все изображения и вложения непосредственно внутри MongoDB. Это просто, но означает, что ваша база данных и каждый mongodump, который вы делаете, будут бесконечно расти по мере того, как пользователи будут вставлять скриншоты. В разделе Admin → Settings → File Upload можно переключить хранилище на локальную файловую систему или S3-совместимое объектное хранилище, а также установить разумный лимит на размер файла. Если ваша команда обменивается целыми библиотеками фотографий, а не отдельными скриншотами, им место на выделенном сервере для фото, а не в базе данных чата. Статья сравнение PhotoPrism и Immich поможет оценить потребление оперативной памяти и требования к резервному копированию для каждого из этих решений. Для небольшой команды 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 последовательно, по одной мажорной версии за раз. При запуске приложение выполняет миграции схемы базы данных. В документации 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 version) после каждого шага. В MongoDB 8.0 эта команда требует явного указания confirm: true, иначе она завершится с ошибкой и сообщением о необходимости повторного запуска с флагом подтверждения:

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

Делайте mongodump перед каждым обновлением любого из компонентов. Это ваша единственная страховка.

Режимы сбоев и точные строки ошибок

Rocket.Chat уходит в цикл перезагрузки сразу после docker compose up, а docker compose logs rocketchat заполняется MongoServerSelectionError. MongoDB запущена, но драйвер не может выбрать первичный узел (primary), и точная строка ошибки указывает на допущенную ошибку. 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 является случайным хешем, выполните повторную инициализацию, используя имя сервиса.

Веб-интерфейс загружается, но процесс входа в систему бесконечно вращается и не завершается. Откройте консоль браузера, и вы увидите WebSocket connection to 'wss://chat.example.com/websocket' failed. Почти всегда это несоответствие ROOT_URL или прокси-сервер, который не передает заголовки обновления (upgrade headers). Убедитесь, что ROOT_URL совпадает с точным публичным адресом, включая https://, и что ваш блок location в nginx устанавливает Upgrade и Connection "upgrade" с помощью proxy_http_version 1.1. Измените настройки и перезапустите docker compose up -d.

Контейнер постоянно завершается, и docker compose ps показывает, что он Restarting. docker compose logs обрывается на середине строки, а sudo dmesg | tail показывает Out of memory: Killed process 12345 (mongod) от oom-killer; код завершения — 137. На сервере закончилась оперативная память. Единственное верное решение — увеличить объем RAM на VPS, минимум до 4 GB. В качестве временной меры добавьте swap и ограничьте кэш MongoDB с помощью --wiredTigerCacheSizeGB в файле command, установив значение ниже стандартного, например 1 для сервера с 4 GB (по умолчанию 1.5) или 0.3 для сервера с 2 GB (по умолчанию около 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. Порт 3000 уже занят, часто это предыдущий контейнер Rocket.Chat, который не завершился корректно, или другое приложение. Найдите процесс с помощью sudo ss -ltnp | grep :3000, остановите его или контейнер, либо измените хостовую часть маппинга портов на 127.0.0.1:3001:3000 и обновите proxy_pass в вашем прокси-сервере в соответствии с новым значением.

FAQ

Действительно ли Rocket.Chat требует Replica Set в MongoDB?

Да, даже для одного сервера с одним узлом базы данных. Rocket.Chat доставляет сообщения в реальном времени, используя MongoDB change streams, а эта функция доступна только в Replica Set; standalone-инстанс mongod не может их открыть. Вам не нужно несколько машин: запустите один контейнер MongoDB с флагом --replSet rs0 и инициализируйте набор из одного участника командой rs.initiate(). Если пропустить этот шаг, драйвер не обнаружит primary-узел, и Rocket.Chat будет бесконечно перезапускаться с ошибкой MongoServerSelectionError: Server selection timed out, так и не завершив загрузку.

Сколько оперативной памяти нужно для self-hosted Rocket.Chat?

Планируйте 4 GB как практический минимум и 8 GB для активной команды. Процесс Node в Rocket.Chat потребляет от 1 до 1.5 GB, а кэш WiredTiger в MongoDB по умолчанию занимает половину от (общего объема RAM минус 1 GB), исходя из предположения, что на сервере больше ничего не запущено. На машине с 2 GB этот кэш, heap процесса Node и накладные расходы самого mongod вступают в конфликт, и OOM killer завершает работу mongod при любой реальной нагрузке, что отражается в логах как Killed с кодом выхода 137. 2 GB достаточно только для ознакомления с ПО на паре тестовых пользователей.

Как настроить HTTPS для Rocket.Chat?

Запустите reverse proxy на том же VPS, который будет выполнять TLS termination и перенаправлять трафик на 127.0.0.1:3000, а в настройках контейнера укажите ROOT_URL, соответствующий вашему публичному https:// адресу. Прокси должен передавать заголовки WebSocket upgrade, иначе авторизация зависнет. Certbot с nginx — самый простой вариант для одного приложения; Traefik удобнее, если вы запускаете несколько контейнеров за одним прокси и хотите автоматизировать управление сертификатами.

Как выполнять резервное копирование self-hosted Rocket.Chat?

Создавайте консистентный дамп базы данных с помощью mongodump вместо простого копирования тома: docker compose exec -T mongodb mongodump --db rocketchat --archive --gzip > backup.archive.gz. Этот архив содержит пользователей, каналы, сообщения и настройки, а также загруженные файлы, если вы оставили хранилище в GridFS. Копируйте архив с сервера, автоматизируйте процесс через cron и периодически проводите тестовое mongorestore на временной машине, чтобы убедиться в работоспособности восстановления.

Как обновить Rocket.Chat, не повредив MongoDB?

Обновляйте Rocket.Chat последовательно, по одной мажорной версии за раз. При запуске приложение выполняет миграции, и документация предупреждает, что пропуск мажорных версий может привести к серьезным проблемам совместимости. Перед изменением тега образа обязательно читайте примечания к каждому релизу. Проверяйте, какие версии MongoDB поддерживает целевой релиз, с помощью curl -s https://releases.rocket.chat/<version>/info | jq .compatibleMongoVersions. При обновлении MongoDB также переходите по одной мажорной версии за раз и устанавливайте setFeatureCompatibilityVersion командой confirm: true после каждого шага. Всегда сначала делайте mongodump.