Введение: почему RocketChat, а не Tox или Matrix
Общаться с командой через Tox не совсем удобно, поскольку если выйти с клиента, новые сообщения можно пропустить. Также неудобно заходить с другого устройства — приходится тащить за собой кучу файлов профиля. Восстановить аккаунт в случае утери нельзя, а поделиться контактом не всегда очевидно, как. Tox удобен для общения один на один, но плохо подходит для командной работы.
Matrix — неплохое решение, но его тоже нужно поднимать на своём сервере. Если заниматься чем-то серьёзным, использовать публичный matrix.org не вариант.
Мне нравится использовать корпоративные мессенджеры — Mattermost или RocketChat. У новичков может возникнуть путаница с настройкой, поэтому в этом гайде я подробно распишу, как поднять RocketChat так, чтобы весь нужный функционал работал корректно.
RocketChat — отличный вариант для приватного командного чата: удобное API, возможность создавать пользователей, выдавать права, добавлять участников в каналы программно. Разворачивается всё в Docker, поэтому при необходимости можно быстро всё удалить.
Выбор сервера для RocketChat
Выбирайте любого российского хостера — не реселлера. Так называемые «абузоустойчивые» хостинги — это скам и переплата. Не добавляйте в чат сомнительных людей, иначе на сервер накинут абузу и хостер его заблокирует.
- Минимум 4 GB RAM
- ОС: Debian 12 (рекомендуемый вариант)
Установка RocketChat на Debian 12: подготовка системы
apt update
apt list --upgradable
apt install -y \
ca-certificates \
curl \
gnupg \
lsb-release
Установка Docker для RocketChat
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
Проверяем установку:
docker --version
docker compose version
Docker Compose файл для развёртывания RocketChat
Создаём рабочую директорию:
mkdir -p /opt/rocketchat && cd /opt/rocketchat
nano docker-compose.yml
Содержимое docker-compose.yml:
version: "3"
services:
rocketchat:
image: rocket.chat:latest
restart: unless-stopped
volumes:
- ./uploads:/app/uploads
environment:
- MONGO_URL=mongodb://mongodb:27017/rocketchat?replicaSet=rs0
- MONGO_OPLOG_URL=mongodb://mongodb:27017/local?replicaSet=rs0
- ROOT_URL=https://your-domain.example
- PORT=3000
- DEPLOY_METHOD=docker
depends_on:
- mongodb
ports:
- "3000:3000"
mongodb:
image: mongo:6.0
restart: unless-stopped
volumes:
- ./data/db:/data/db
command: mongod --replSet rs0 --oplogSize 128
mongo-init-replica:
image: mongo:6.0
command: >
bash -c "sleep 5 && mongosh mongodb://mongodb:27017 --eval '
rs.initiate({
_id: \"rs0\",
members: [{ _id: 0, host: \"mongodb:27017\" }]
})'"
depends_on:
- mongodb
Важно: замените ROOT_URL на свой домен — иначе RocketChat будет генерировать некорректные ссылки в приглашениях и уведомлениях.
Запускаем контейнеры:
docker compose up -d
Проверка WebSocket и первичная настройка администратора
Проверяем, что все контейнеры запустились:
docker compose ps
Переходим в браузере по адресу http://ip_vps:3000 и проходим настройку: придумываем логин администратора, пароль, вводим рабочую почту, на которую придёт код подтверждения.
Создаём второй тестовый аккаунт и проверяем, приходят ли сообщения в реальном времени без перезагрузки страницы — так мы убеждаемся, что WebSocket-соединение работает корректно. С аккаунта администратора проверяем доступ в панель управления и создание чатов.
Если на этом этапе возникли ошибки — смотрим логи контейнера и консоль браузера:
docker compose logs --tail=20 rocketchat
Решение проблем с репликацией MongoDB
Проверяем статус репликации:
docker run -it --rm --network container:rocketchat-mongo-1 mongo:6.0 mongosh
rs.status()
Если появляется ошибка:
MongoServerError[InvalidReplicaSetConfig]: Our replica set config is invalid or we are not a member of it
Это значит, что MongoDB зарегистрировала себя во внутреннем реестре Docker под автоматически присвоенным именем контейнера вместо имени сервиса mongo, указанного в MONGO_URL. Исправляем:
docker exec -it rocketchat-mongo-1 mongosh
cfg = rs.conf()
cfg.members[0].host = "mongo:27017"
rs.reconfig(cfg, { force: true })
rs.status()
После этого в выводе должно появиться:
"members": [
{
"name": "mongo:27017",
"stateStr": "PRIMARY",
...
}
]
Часть функционала RocketChat недоступна без TLS-соединения — разберём его настройку ниже.
Настройка TLS-шифрования для RocketChat
Поскольку мы не привязываем доменное имя (Let’s Encrypt не выпускает сертификаты на IP-адреса), генерируем самоподписанный сертификат:
openssl req -x509 -newkey rsa:2048 -nodes -keyout rocketchat.key -out rocketchat.crt -days 365 -subj "/CN=ip_vps" -addext "subjectAltName=IP:ip_vps"
Установка и настройка Nginx как reverse proxy
apt install nginx
Удаляем дефолтный конфиг:
rm /etc/nginx/sites-available/*
rm /etc/nginx/sites-enabled/*
Создаём конфигурацию:
nano /etc/nginx/sites-available/rocketchat
server {
listen 443 ssl;
server_name ip_vps;
ssl_certificate /root/rocketchat/rocketchat.crt;
ssl_certificate_key /root/rocketchat/rocketchat.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # для WebSocket
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
server {
listen 80;
server_name ip_vps;
return 301 https://$host$request_uri;
}
Создаём symlink и проверяем конфигурацию:
ln -s /etc/nginx/sites-available/rocketchat /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
В переменных окружения RocketChat меняем протокол:
- ROOT_URL=https://ip_vps
- PORT=3000
Порт 3000 у самого RocketChat остаётся прежним — nginx проксирует запросы с 443 на 3000. Браузер будет предупреждать о самоподписанном сертификате (это ожидаемо при работе по IP без домена), но соединение уже зашифровано.
Защита панели администратора: Basic Auth
apt install apache2-utils
htpasswd -c /etc/nginx/.htpasswd your_secure_login
server {
listen 443 ssl;
server_name ip_vps;
ssl_certificate /root/rocketchat/rocketchat.crt;
ssl_certificate_key /root/rocketchat/rocketchat.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost: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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
server {
listen 80;
server_name ip_vps;
return 301 https://$host$request_uri;
}
systemctl reload nginx
Закрываем прямой доступ к порту RocketChat
Раз трафик теперь идёт через nginx на 443 порт, порт 3000 нужно закрыть от внешнего доступа — иначе Basic Auth не имеет смысла, так как RocketChat остаётся доступен напрямую в обход nginx:
services:
rocketchat:
image: registry.rocket.chat/rocketchat/rocket.chat:latest
restart: unless-stopped
volumes:
- rocketchat_data:/app/uploads
environment:
- PORT=3000
- ROOT_URL=https://ip_vps
- MONGO_URL=mongodb://mongo:27017/rocketchat
- MONGO_OPLOG_URL=mongodb://mongo:27017/local
depends_on:
- mongo
ports:
- "127.0.0.1:3000:3000"
mongo:
image: mongo:6.0
restart: unless-stopped
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
volumes:
- mongo_data:/data/db
- mongo_config:/data/configdb
volumes:
rocketchat_data:
mongo_data:
mongo_config:
Закрытая регистрация и права пользователей
Отключаем открытую регистрацию через /admin/settings/Accounts, чтобы новые аккаунты создавал только администратор.
Настраиваем права доступа для ролей в разделе /admin/permissions — здесь можно ограничить, кто может создавать каналы, приглашать пользователей и управлять настройками сервера.
Новых пользователей создаём вручную через /admin/users, а в /admin/settings/Accounts запрещаем пользователям самостоятельно менять никнейм и логин — это исключает путаницу и упрощает модерацию.
Итог
Если повторить все шаги по порядку, RocketChat разворачивается с рабочим TLS-шифрованием, закрытой регистрацией, защищённой панелью администратора и без открытого доступа к порту приложения напрямую. Для генерации сложных логинов и паролей можно использовать любой надёжный генератор паролей.
Отключаем уведомления rocket.cat о невалидном URL
Если после смены ROOT_URL или работы без домена системный бот rocket.cat присылает сообщения о невалидном URL, отключить их можно через панель администратора:
/admin/settings/Message
Здесь находится настройка, отвечающая за системные уведомления такого типа — достаточно выключить соответствующий тумблер.
Как убрать бота rocket.cat из статуса «онлайн» или удалить его профиль
Если недостаточно просто отключить уведомления и хочется, чтобы системный бот не отображался как активный пользователь, это делается напрямую через базу данных MongoDB:
docker run -it --rm --network container:rocketchat-mongo-1 mongo:6.0 mongosh
Переводим всех пользователей с типом bot в статус оффлайн и деактивируем их:
db.users.updateMany(
{ type: "bot" },
{
$set: {
active: false,
status: "offline",
statusDefault: "offline",
roles: []
}
}
)
Если нужно только снять роли, не деактивируя аккаунт полностью:
db.users.updateMany(
{ type: "bot" },
{ $set: { roles: [] } }
)
После изменений перезапускаем контейнер, чтобы RocketChat подхватил новое состояние:
docker restart rocketchat-rocketchat-1
Восстановление доступа админа при утере пароля
Если пароль от административной учётной записи утерян, но в браузере осталась активная сессия — самый быстрый способ восстановить доступ следующий:
- Создайте новую учётную запись
- Сразу при создании назначьте ей роли
leaderиadmin
Важный нюанс: если попытаться добавить роль администратора уже существующему пользователю, RocketChat запросит подтверждение паролем текущей сессии — и если пароль неизвестен, операция не пройдёт. А вот при создании новой учётной записи роли можно указать сразу, без дополнительного подтверждения — это и есть обходной путь для восстановления доступа.