Заголовок: Rocket.Chat на своём сервере: развёртывание и настройка
Развёртывание Rocket.Chat на своём сервере даёт компании полный контроль над перепиской: история сообщений, файлы и метаданные остаются внутри периметра, а не уходят во внешние облака. Мы в IT For Prof разворачиваем платформу для банков и производственных предприятий, поэтому ниже — практический разбор без шаблонных сценариев.
Когда Rocket.Chat закрывает корпоративные задачи
Платформа написана на TypeScript и поставляется в трёх вариантах — self-hosted, облачный и air-gapped. Для российского заказчика, который обязан соблюдать ФЗ-152, интересны два последних. Мы рекомендуем Rocket.Chat, когда нужны три вещи одновременно: мессенджер с каналами, тредами и звонками; встроенные SSO, сквозное шифрование и ролевой доступ; расширяемость через Rocket.Chat Marketplace и интеграции с внешними системами.
Критерии выбора на наших проектах:
- организация уходит со Slack или Microsoft Teams и не готова к федерации Matrix;
- нужны веб-клиент и мобильные приложения «из коробки», без сборки форков;
- ИБ требует SSO через Active Directory и журналирование действий администраторов;
- планируется интеграция с Jira, GitLab, Zabbix и собственными API через webhooks и Apps-Engine.
Mattermost выигрывает там, где хватает одного узла и нужен Postgres вместо MongoDB. Matrix мы берём, когда требуется межорганизационная федерация. Rocket.Chat побеждает на связке «внутренний чат плюс виджет поддержки на сайте»: одна платформа закрывает оба контура.
Ресурсы под 50, 200 и 500 сотрудников
Считаем не от числа лицензий, а от профиля нагрузки: дневная активность, количество открытых клиентов, объём вложений. Узкое место — MongoDB и память Node.js, а не CPU, поэтому сначала диск и оперативная память, потом ядра.
До 50 сотрудников — один узел: несколько ядер, SSD под полугодовую переписку, MongoDB на той же машине, бэкап по сети. От 200 сотрудников MongoDB выносим на отдельный сервер и собираем replica set из трёх узлов. Приложение масштабируем горизонтально: два контейнера за Nginx, общий S3-бакет под uploads, отдельный том под логи. От 500 сотрудников — кластер: три узла MongoDB, минимум три экземпляра приложения, выделенный TURN-сервер для голосовых и видеозвонков, отдельная нода под интеграции и омниканальность, отдельный мониторинг через Prometheus с node-exporter и mongodb-exporter.
У одного клиента мы получили остановку виртуальной машины из-за тонкого диска и снапшотов гипервизора без согласования с MongoDB: база раздулась, снапшот не удалялся, на датасторе закончилось место. С тех пор для MongoDB используем только толстый (eager-zeroed) диск и отдельный том под журнал.
Развёртывание через Docker Compose и replica set
Из официальных способов установки выбираем Docker Compose для одного-двух узлов, для кластера от 500 пользователей переходим на Kubernetes с Helm-чартом вендора. MongoDB обязана работать в режиме replica set даже на одном узле — современный Rocket.Chat использует change streams и без replica set не стартует.
Первый запуск делаем поэтапно: поднимаем MongoDB, инициализируем replica set отдельной командой, проверяем rs.status на PRIMARY и health: 1, и только потом стартуем приложение. На наших проектах в трёх случаях из десяти Rocket.Chat успевал записать первые документы до инициализации replica set — потом приходилось чистить базу. Разделение фаз снимает этот риск.
Версии образов фиксируем точными тегами, не latest, иначе docker compose up после перезагрузки сервера подтянет мажорное обновление. Тома под mongo, mongo-config и uploads выносим в /opt/rocketchat/data, бэкапы — в отдельный каталог рядом.
HTTPS через Nginx и первичная настройка администратора
HTTPS терминируем на отдельном Nginx: так мы управляем сертификатами и rate limit независимо от перезапусков приложения. Контейнер Rocket.Chat слушает только внутренний интерфейс. В конфиге Nginx критичны три блока: проксирование WebSocket с заголовками Upgrade и Connection, таймауты до 600 секунд для долгоживущих соединений, client_max_body_size под максимальный размер вложения, согласованный с настройкой Rocket.Chat. Расходящиеся значения дают непонятные ошибки на полпути загрузки крупных файлов.
Сертификат для внешнего домена выпускаем через Let's Encrypt с автопродлением certbot, для закрытого контура — корпоративным внутренним УЦ. Переменная ROOT_URL должна точно совпадать со схемой и хостом, под которыми пользователи открывают сервис, иначе ссылки в письмах и пуш-уведомлениях ломаются.
В мастере первичной настройки задаём владельца, имя рабочего пространства и закрытую политику регистрации. В Workspace → Settings запрещаем регистрацию по форме, отключаем публичные каналы по умолчанию, включаем обязательное подтверждение e-mail. Встроенные интеграции и бота rocket.cat с дефолтным правом отправки в любые каналы отключаем до того, как заведём первого пользователя: на одном проекте через зарегистрированный webhook внешний подрядчик залил рекламу во внутренний канал.
Интеграция с Active Directory и LDAP
В админке в разделе LDAP задаём адрес контроллера домена, шифрование (LDAPS на порту 636 либо StartTLS на 389), сервисную учётную запись с правом чтения каталога, базовый DN и фильтр. Для AD фильтр исключает отключённые учётки по userAccountControl, служебные и компьютерные объекты.
Маппинг атрибутов выстраиваем явно: username — sAMAccountName, email — mail, name — displayName. Смена маппинга после первой синхронизации даёт дубли учёток, разбирать которые вручную дольше, чем один раз согласовать поля с владельцем каталога. Группы AD сопоставляем с ролями Rocket.Chat (admin, bot, livechat-agent) или с каналами; синхронизацию ставим раз в час, полный пересчёт ролей — ночью.
Перед включением входа по LDAP проверяем связку командой ldapsearch с сервера Rocket.Chat — она подтверждает сеть до контроллера домена, приём сертификата LDAPS и работу фильтра. Только после ручной проверки включаем Login with LDAP и тестируем пилотной учёткой. Широкий фильтр на каталог в десятки тысяч записей с фоновой синхронизацией один раз дал нам деградацию контроллера домена утром, когда сотрудники массово заходили. С тех пор для крупных каталогов запускаем ступенчато: сначала узкий OU, потом расширяем.
Бэкап MongoDB и uploads, восстановление за 15 минут
Бэкап состоит из двух согласованных компонентов: дамп MongoDB и копия каталога uploads. Без uploads восстановленная база покажет в каналах ссылки на отсутствующие файлы — формально сервис работает, но история неполная.
MongoDB снимаем mongodump с флагом --oplog: для replica set это обязательно, иначе при восстановлении часть коллекций отстаёт от других на минуты. Файлы загрузок — rsync или tar для локального тома, либо версионирование объектов на стороне S3-совместимого хранилища: это даёт бесплатные «бэкапы за период» и спасает от ошибочного удаления одного файла администратором. Расписание строим по правилу 3-2-1: ежедневный инкрементальный бэкап на отдельный сервер, еженедельный полный с выносом во второй ЦОД, ежемесячный архив с долгим сроком хранения.
Восстановление за пятнадцать минут возможно только на подготовленной заранее площадке: чистый сервер с тем же docker-compose, той же мажорной версией Rocket.Chat и тем же DNS-именем. Тестовое восстановление мы прогоняем раз в квартал — без этого бэкап остаётся гипотезой, а не процедурой.
Команда IT For Prof разворачивает Rocket.Chat в инфраструктуре заказчика под ключ: подбор ресурсов под профиль нагрузки, настройка LDAP и hardening по security-guidelines, отказоустойчивый кластер MongoDB и бэкапы с проверенным восстановлением. Если уходите со Slack или Teams в свой периметр — мы проходим этот путь вместе с инженерами заказчика.