#!/bin/bash # Rocket.Chat install hooks. # # Rocket.Chat needs its Mongo to be a replica set, because realtime message # delivery works by tailing the oplog and a standalone mongod has no oplog. The # official mongo image does not initiate a set on its own, so we do it once here # after the containers come up. rocketchat_install_post_start() { local app_name="$1" ((menu_number++)) echo "" echo "---- $menu_number. Initiating the MongoDB replica set for $app_name" echo "" # Wait for mongod to answer at all. It has to be listening before # rs.initiate() can be sent, and on a cold volume the first boot spends a # while building journal files. local attempts=0 while ((attempts < 45)); do if runFileOp docker exec rocketchat-db mongosh --quiet --eval "db.adminCommand({ping:1}).ok" 2>/dev/null | grep -q 1; then break fi sleep 2 ((attempts++)) done if ((attempts >= 45)); then isError "rocketchat-db never started accepting connections — replica set not initiated." isNotice "Rocket.Chat will keep restarting until it is. Once the database is up, run:" isNotice " docker exec rocketchat-db mongosh --eval 'rs.initiate({_id:\"rs0\",members:[{_id:0,host:\"rocketchat-db:27017\"}]})'" return 0 fi # Idempotent: a reinstall over restored data, or a rerun of this hook, finds # the set already configured and must not re-initiate it — rs.initiate() on # a live set errors out and would leave the step looking failed. if runFileOp docker exec rocketchat-db mongosh --quiet --eval "rs.status().ok" 2>/dev/null | grep -q 1; then isSuccessful "MongoDB replica set rs0 already initiated — leaving it alone." else local result result=$(runFileOp docker exec rocketchat-db mongosh --quiet --eval \ 'rs.initiate({_id:"rs0",members:[{_id:0,host:"rocketchat-db:27017"}]})' 2>&1) checkSuccess "Initiating MongoDB replica set rs0" fi # Election of the single member takes a moment. Rocket.Chat exits rather # than retries if it connects before a primary exists, so wait for the node # to report itself primary before handing control back. attempts=0 while ((attempts < 30)); do if runFileOp docker exec rocketchat-db mongosh --quiet --eval "db.hello().isWritablePrimary" 2>/dev/null | grep -q true; then break fi sleep 2 ((attempts++)) done # Restart so Rocket.Chat reconnects immediately instead of waiting out its # own backoff after the crash-loop it was in while the set was forming. dockerComposeRestart "$app_name" } rocketchat_install_post() { local app_name="$1" echo "" isNotice "Rocket.Chat first run:" echo "" echo " Open the web interface and complete the setup wizard — the first" echo " account you create there becomes the workspace administrator." echo "" echo " For voice and video, point Rocket.Chat at your Jitsi Meet server" echo " under Admin -> Settings -> Video Conference -> Jitsi." echo "" }