SSD Nodes Learn Hosting plans →
Посібники Matt ConnorВід Matt Connor

Rocket.Chat у Docker Compose: self-hosting на VPS

Запустіть Rocket.Chat на VPS через Docker Compose: налаштуйте replica set MongoDB з одного вузла, TLS і резервні копії, а також виправте типові помилки.

Що ви створюєте

Приватний командний чат, який повністю належить вам: Rocket.Chat працює на вашому VPS у Docker Compose, TLS завершується на reverse proxy, а всі повідомлення зберігаються в базі даних MongoDB, яку можна резервно копіювати та переносити. Rocket.Chat — зрілий open-source аналог Slack і Teams із каналами, приватними повідомленнями, тредами, обміном файлами, голосовими та відеодзвінками. Усе це працює на обладнанні, яке ви орендуєте та контролюєте. Водночас це не єдиний надійний варіант. Якщо ви ще обираєте платформу, порівняння Mattermost, Rocket.Chat, Synapse і Zulip допоможе оцінити чинники, які часто створюють проблеми згодом: RAM, базу даних, мобільні push-сповіщення, SSO та оновлення. Застосунок працює в одному контейнері та запускається за кілька хвилин. Усе, що фактично може вийти з ладу, пов’язане з базою даних поруч із ним. Тому більша частина цього посібника присвячена MongoDB і, зокрема, одній вимозі, яка спочатку дивує майже всіх: Rocket.Chat не працюватиме з автономним екземпляром MongoDB. Йому потрібен replica set, навіть якщо цей «набір» складається з одного вузла.

Попередні вимоги та розрахунок RAM, про який зазвичай не говорять

Реалістичний мінімум для невеликої команди — 2 vCPU і 4 GB RAM. Процесу Node.js у Rocket.Chat потрібно приблизно 1–1.5 GB RAM, а кеш WiredTiger у MongoDB за замовчуванням має розмір, більший із двох значень: 50% від (загальний обсяг RAM мінус 1 GB) або 0.256 GB. Це значення розраховане на те, що mongod використовує сервер одноосібно: воно визначається за загальним обсягом RAM і не враховує пам’ять, яку вже використовує Node. Тому на сервері з 4 GB воно становить 1.5 GB, а на сервері з 2 GB — приблизно 0.5 GB. Ця пам’ять додається до heap Node, власного використання пам’яті mongod поза кешем і потреб операційної системи. На VPS із 2 GB вони запускаються одночасно, але щойно з’являється реальний трафік, починаються проблеми: MongoDB збільшує кеш, Node збільшує heap, ядру бракує сторінок пам’яті, і OOM killer завершує найбільший процес, зазвичай mongod. Контейнер виводить Killed, Docker перезапускає його, і під навантаженням, яке сервер мав би легко витримувати, чат-сервер припиняє працювати кожні кілька хвилин. 2 GB достатньо, щоб протестувати систему з двома користувачами, але для командного сервера цього недостатньо. Почніть із 4 GB, а якщо очікуєте десятки одночасних користувачів, відеодзвінки або зростання історії завантажень, виділіть 8 GB. Враховуйте також усі інші служби на сервері: розміщення робочого простору AFFiNE у стилі Notion на тому самому VPS додає ще чотири контейнери, які конкурують за ті самі сторінки пам’яті, тому їхній обсяг RAM потрібно додати до потреб Rocket.Chat, а не відняти від них.

До початку роботи також потрібно підготувати три речі. Доменне ім’я із записом A, що вказує на публічну IP-адресу VPS. Для функцій реального часу та мобільних клієнтів Rocket.Chat потрібне стабільне ім’я хоста, а не просто IP-адреса. Порти 80 і 443 мають бути відкриті у firewall сервера та в мережевому firewall провайдера. У більшості панелей це окремі засоби керування. Також потрібен чистий Ubuntu 24.04 на KVM VPS із root або sudo. Якщо ви ще вирішуєте, чи варто запускати chat-сервер як першу службу, посібник про те, що варто self-host у 2026 році допоможе оцінити компроміси.

Встановіть Docker Engine і плагін Compose

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

Файл Compose: MongoDB як одновузловий replica set

Саме тут часто припускаються помилок, тому читайте уважно. Rocket.Chat використовує change streams, щоб у реальному часі передавати нові повідомлення підключеним клієнтам, а change streams доступні лише в replica set. Якщо вказати Rocket.Chat звичайний автономний 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, тому драйвер усе одно виявить replica set і надсилатиме операції до 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, який показує, чи є цей реліз версією з довгостроковою підтримкою, яку варто зафіксувати для сервера, що не потребує постійного ручного супроводу. Не кожен проєкт публікує версіонований образ. У такому разі фіксацію версії потрібно виконати на рівні вихідного коду: самостійне розгортання трекера тренувань openGym означає перевірити конкретний git-тег і зібрати проєкт із нього, а не стежити за гілкою, яка постійно змінюється.

Ініціалізуйте replica set

Запустіть stack:

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". Якщо виконати звичайний rs.initiate() без списку members, MongoDB оголосить replica set під внутрішнім hostname контейнера — випадковим хешем на кшталт a1b2c3d4e5f6. Rocket.Chat, підключаючись зі свого контейнера, не зможе розв’язати це ім’я. Через це MongoDB driver не зможе виконати DNS-розв’язання і безкінечно циклічно записуватиме в журнал MongoServerSelectionError: getaddrinfo ENOTFOUND a1b2c3d4e5f6. Завжди ініціалізуйте replica set із явним іменем service, яке відповідає вашому 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
+--------------------------------------------+

Перший запуск повільний: застосунок виконує міграції бази даних і створює індекси, тому зачекайте хвилину-дві, перш ніж починати пошук проблеми. Якщо в журналі натомість повторюється MongoServerSelectionError: Server selection timed out after 30000 ms з описом топології типу ReplicaSetNoPrimary, replica set не ініціалізовано; якщо повторюється getaddrinfo ENOTFOUND із випадковим хешем, його ініціалізовано з неправильним хостом. У будь-якому разі поверніться на один крок назад. Коли побачите SERVER RUNNING, Rocket.Chat почне прослуховувати 127.0.0.1:3000, і настане час налаштувати перед ним справжнє hostname та TLS.

Розмістіть його за TLS

Ніколи не відкривайте Rocket.Chat через звичайний HTTP. Якщо один раз увійти через http://, пароль адміністратора стане доступним будь-кому на мережевому шляху. Завершуйте TLS у reverse proxy на тому самому сервері та передавайте запити до 127.0.0.1:3000. Важливі дві речі: проксі має передавати заголовки оновлення WebSocket, оскільки Rocket.Chat працює в реальному часі й без них не працюватиме, а значення ROOT_URL у контейнері має точно відповідати публічній HTTPS-адресі, яку вводять користувачі.

Почніть зі звичайного HTTP server block nginx, який проксуватиме запити до застосунку та передаватиме заголовки оновлення. Збережіть його як /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-застосунків: додайте labels маршрутизатора й сервісу до сервісу rocketchat, і Traefik сам запитуватиме та поновлюватиме сертифікат, без жодного блока nginx. У будь-якому разі встановіть ROOT_URL у https://chat.example.com в compose.yml і повторно виконайте sudo docker compose up -d, щоб контейнер отримав це значення. Якщо сервер має бути доступним лише з вашої внутрішньої мережі, а не з публічного інтернету, розмістіть перед ним self-hosted WireGuard VPN на VPS і прив’яжіть проксі до адреси тунелю.

Початковий майстер налаштування

Відкрийте https://chat.example.com, і Rocket.Chat проведе вас через короткий майстер. Спочатку створіть обліковий запис адміністратора: укажіть справжнє ім’я, ім’я користувача, email і надійний пароль. Це єдиний наявний обліковий запис, тому не втрачайте його. Далі заповніть інформацію про організацію та сервер: назву, галузь, розмір, назву сайту й мову за замовчуванням. Це косметичні параметри. Заповніть їх і продовжуйте. Потім виберіть параметр, який справді має значення: зареєструвати цей workspace у Rocket.Chat Cloud або залишити його автономним.

Реєстрація вмикає push-сповіщення для мобільних пристроїв через gateway Rocket.Chat і marketplace додатків. Водночас вона створює зв’язок із cloud-площиною керування Rocket.Chat. Push-сповіщення, надіслані через gateway, також зараховуються до місячного ліміту вашого workspace. Автономний режим зберігає сервер повністю приватним і не залежним від зовнішніх сервісів. Однак офіційні застосунки для iOS та Android перестають отримувати push-сповіщення, оскільки в документації Rocket.Chat зазначено, що ці застосунки працюють лише з його cloud gateway. Gateway не запускається для незареєстрованого workspace.

Обійти це обмеження можна за допомогою власної white-label збірки мобільного застосунку. Вимкніть gateway у налаштуваннях Push, додайте власні сертифікати APNs і облікові дані Firebase Cloud Messaging, а користувачам запропонуйте встановити ваш застосунок замість офіційного. Виберіть автономний режим, якщо приватність є головною вимогою, користувачі працюють переважно у web-застосунку або ви готові випустити власний мобільний застосунок. Виберіть реєстрацію, якщо push-сповіщення в офіційних застосунках є обов’язковими. Пізніше вибір можна змінити в розділі Admin.

Захистіть систему до того, як запросите користувачів

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

Також визначте, де зберігатимуться завантажені файли. За замовчуванням сховище 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

Цей один стиснений за допомогою gzip архів містить увесь робочий простір: користувачів, канали, повідомлення, налаштування та, якщо ви залишили завантаження у GridFS, також файли. Якщо ви перенесли завантаження у файлову систему або S3, створюйте резервну копію цього сховища окремо. Для відновлення в новому стеку спочатку ініціалізуйте набір реплік, а потім виконайте:

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

Скопіюйте архів за межі сервера: у об’єктне сховище, на інший сервер або в будь-яке інше місце, де вихід VPS з ладу не знищить резервну копію. Запускайте створення дампу щоночі через cron. Резервна копія, з якої ви жодного разу не виконували відновлення, — це лише надія, а не резервна копія. Один раз перевірте відновлення на тимчасовому VPS, щоб переконатися, що воно працює, перш ніж це знадобиться.

Оновлення: фіксуйте теги, читайте примітки, дотримуйтеся матриці сумісності Mongo

Два правила роблять оновлення передбачуваними. По-перше, оновлюйте 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, переходьте на одну мажорну версію за раз і після кожного переходу встановлюйте версію сумісності функцій. У 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 оголосила hostname контейнера, який неможливо розв’язати. Виконайте діагностику за допомогою 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. Переконайтеся, що 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 показує 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 доставляє повідомлення в реальному часі за допомогою change streams MongoDB, а change streams доступні лише для replica set; автономний mongod не може відкрити такий потік. Кілька машин не потрібні: запустіть один контейнер MongoDB з --replSet rs0 та ініціалізуйте set з одним учасником за допомогою rs.initiate(). Якщо пропустити цей крок, драйвер не знаходить primary, тому Rocket.Chat зациклюється на перезапусках із MongoServerSelectionError: Server selection timed out і не завершує запуск.

Скільки RAM потрібно для 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 конкурують за пам’ять, а killer out-of-memory завершує mongod за будь-якого реального навантаження. У журналах з’являється Killed, а код завершення дорівнює 137. Двох GB достатньо лише для оцінювання програмного забезпечення з кількома тестовими користувачами.

Як розмістити Rocket.Chat за HTTPS?

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

Як створити резервну копію self-hosted Rocket.Chat?

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

Як оновити Rocket.Chat і не порушити роботу MongoDB?

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