[ACTION REQUIRED] Moving from Bitnami to Official MongoDB Chart

Overview

We will be removing Bitnami MongoDB from the Rocket.Chat Helm chart. This guide walks you through setting up MongoDB externally using the MongoDB Community Operator and migrating your existing data.

What’s changing:

  • Bitnami MongoDB will no longer be updated in the Rocket.Chat Chart.
  • Bitnami MongoDB will be getting removed as a subchart dependency in Rocket.Chat’s Chart.
  • MongoDB will now need to be deployed and managed independently using the MongoDB Community Operator
  • You have full control over MongoDB deployments and updates, separate from Rocket.Chat updates

Background & Why This Change Was Necessary

Over the past several years, Bitnami has been the go-to provider for providing MongoDB in our Helm chart. However, significant changes in the community have necessitated a shift in strategy:

Recent Events:

  1. Bitnami Acquisition Impact: Bitnami was acquired by VMware (which itself was previously acquired by Broadcom). Following this acquisition, the decision was made to discontinue support for their legacy images and charts that have been the foundation for countless deployments in the community. Rather than continue community support, users are now directed to paid enterprise solutions.

  2. MongoDB CVE & Lack of Updates: A critical security vulnerability (CVE) was recently discovered in MongoDB. With Bitnami no longer publishing updated images, we face an impossible situation: we cannot recommend users simply update their image to patch the vulnerability, as Bitnami will not be releasing any new images.

  3. MongoDB EOL versions: MongoDB ends support for older versions of MongoDB so Rocket.Chat needs to keep updating which version we support. MongoDB 7 and 8 both are not present and will not be released by Bitnami

The Solution: To ensure security, continued support, and access to updated MongoDB versions, we are updating our recommendation to use the MongoDB Helm chart published by MongoDB. This chart is actively maintained by MongoDB and receives regular security updates and feature enhancements. We’re recommending deploying MongoDB 8.2, the latest version, which includes the latest security patches and performance improvements.

Important Notes Before You Begin

:warning: Please read carefully:

  • If you’re already using an external MongoDB instance (not running MongoDB inside your Kubernetes cluster via Helm), you are not affected by this change. You can skip this migration.
  • Data backup is critical. Migrating to external MongoDB requires careful data handling. A backup is essential before proceeding.
  • After this migration: MongoDB will be running in your Kubernetes cluster as an external service (from Rocket.Chat’s perspective). You maintain full control over the MongoDB deployment and can manage it independently from Rocket.Chat updates.

Step-by-Step Migration Guide

This migration requires a brief period of downtime while you transition your data from the Bitnami chart to a standalone MongoDB deployment via the official MongoDB Helm chart.

Before you start

Please make sure you have kubectl and helm tools installed on your machine.

Going forward you will see:
<namespace> and <release-name> a lot. If you don’t remember those you can run:

helm list -A

You should see an output like this:

❯ helm list -A
NAME                            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                           APP VERSION
rocketchat                      rocketchat      2               2026-01-16 14:38:18.743582 -0600 CST    deployed        rocketchat-6.29.0               8.0.1

In my case:

<release-name> -> rocketchat
<namespace> -> rocketchat

Step 1: Stop Rocket.Chat

First, stop the Rocket.Chat deployment to ensure no new data is written during the transition:

# Scale down ALL services and microservices to 0 replicas
# This includes the main rocketchat deployment AND all microservices
kubectl scale deployment -n <your-namespace> \
  <release-name>-rocketchat \
  <release-name>-account \
  <release-name>-authorization \
  <release-name>-ddp-streamer \
  <release-name>-presence \
  --replicas=0

# Wait for pods to terminate
kubectl wait --for=delete pod -l app.kubernetes.io/name=rocketchat -n <your-namespace> --timeout=300s

:warning: Important: Make sure to scale down ALL deployments, not just the main rocketchat deployment. If you have microservices enabled, you need to scale down all of them (account, authorization, ddp-streamer, presence) to ensure no writes occur during migration.

This gives you a clean window to backup and migrate your data without any writes happening.

Step 2: Backup Your MongoDB Data

Create a backup of your current MongoDB data from the Bitnami chart. This is the most critical step.

# Identify your MongoDB pod
# The pod name may vary depending on your release name, but typically looks like:  <release-name>-mongodb-0
kubectl get pods -n <your-namespace> | grep mongodb

# Get the MongoDB root password from the secret
MONGO_ROOT_PASSWORD=$(kubectl get secret <release-name>-mongodb -n <your-namespace> \
  -o jsonpath='{.data.mongodb-root-password}' | base64 -d)
echo "Root password: $MONGO_ROOT_PASSWORD"

# Create a backup using mongodump
# IMPORTANT: Use ?authSource=admin to backup ALL databases, not just admin
kubectl exec -it <release-name>-mongodb-0 -n <your-namespace> -- \
  mongodump --uri="mongodb://root:${MONGO_ROOT_PASSWORD}@localhost:27017/?authSource=admin" --out /tmp/backup

# Copy the backup out of the pod to your local machine
kubectl cp <your-namespace>/<release-name>-mongodb-0:/tmp/backup ./mongodb-backup

:warning: Critical Notes:

  • The Bitnami MongoDB chart creates an auto-generated root password stored in the <release-name>-mongodb secret
  • Use ?authSource=admin in the connection string to ensure ALL databases are backed up
  • The Rocket.Chat data is in the rocketchat database
  • Your backup should contain a rocketchat/ directory

Verify your backup was created successfully:

ls -la ./mongodb-backup
du -sh ./mongodb-backup

Step 3: Deploy the Official MongoDB Helm Chart

Now deploy the official MongoDB Kubernetes operator and create a MongoDB community instance running MongoDB 8.2.

Step 3a: Prerequisites

Take note of the storageclass you’ll need it.

# Check available StorageClasses
kubectl get storageclass

Step 3b: Add the MongoDB Helm repository

helm repo add mongodb https://mongodb.github.io/helm-charts
helm repo update

Step 3c: Install the MongoDB Kubernetes Operator

:warning: Important: Do NOT install the CRDs separately! The operator chart manages them automatically.

helm install mongodb-kubernetes-operator mongodb/mongodb-kubernetes \
  -n <your-namespace>

Wait for the operator to be ready:

kubectl rollout status deployment/mongodb-kubernetes-operator \
  -n <your-namespace> \
  --timeout=300s

Step 3d: Create MongoDB User Secrets and SCRAM Credentials

Create a file named mongodb-secrets.yaml with the following contents.

:warning: REQUIRED: Replace all <your-secure-*-password> values with actual secure passwords.

---
apiVersion: v1
kind: Secret
metadata:
  namespace: <your-namespace>
  name:  mongodb-admin-password
type: Opaque
stringData:
  password: <your-secure-admin-password>

---
apiVersion: v1
kind: Secret
metadata:
  namespace: <your-namespace>
  name: mongodb-rocketchat-password
type:  Opaque
stringData:
  password: <your-secure-rocketchat-password>

---
apiVersion: v1
kind: Secret
metadata:
  namespace: <your-namespace>
  name: metrics-endpoint-password
type: Opaque
stringData:
  password:  <your-secure-prometheus-password>

---
apiVersion: v1
kind: Secret
metadata:
  namespace: <your-namespace>
  name: admin-scram-credentials
type: Opaque
stringData:
  username: admin
  password: <your-secure-admin-password>

---
apiVersion: v1
kind: Secret
metadata:
  namespace: <your-namespace>
  name: rocketchat-scram-credentials
type: Opaque
stringData:
  username: rocketchat
  password:  <your-secure-rocketchat-password>

Apply the secrets:

kubectl apply -f mongodb-secrets.yaml

Step 3e: Deploy the MongoDB Community Resource

Create a file named mongodb-community. yaml with the following contents.

:warning: REQUIRED: Replace <your-storage-class> with your actual StorageClass name you got earlier.

apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: mongodb
  namespace: <your-namespace>
spec:
  members:  3
  type: ReplicaSet
  version: "8.2.3"
  security:
    authentication: 
      modes: ["SCRAM"]
    tls: 
      enabled: false
  users:
  - name: admin
    db: admin
    passwordSecretRef:
      name:  mongodb-admin-password
    scramCredentialsSecretName: admin-scram-credentials
    roles:
    - name: root
      db: admin
  - name: rocketchat
    db: rocketchat
    passwordSecretRef:
      name:  mongodb-rocketchat-password
    scramCredentialsSecretName: rocketchat-scram-credentials
    roles:
    - name: readWrite
      db: rocketchat
  prometheus:
    username: prometheus-username
    passwordSecretRef:
      name:  metrics-endpoint-password
  statefulSet:
    spec:
      volumeClaimTemplates:
      - metadata:
          name: data-volume
        spec:
          accessModes: ["ReadWriteOnce"]
          storageClassName: <your-storage-class>
          resources:
            requests:
              storage: 50Gi
      template:
        spec:
          containers:
          - name: mongod
            resources:
            # set these to what are appropriate for your Rocket.Chat deployment
              limits:
                cpu: 1500m
                memory: 6Gi
              requests:
                cpu: 500m
                memory: 1Gi

Apply the MongoDB resource:

kubectl apply -f mongodb-community.yaml

Step 3f: Wait for MongoDB to be ready

# Check MongoDB pod status
kubectl get pods -n <your-namespace> | grep mongodb

# Wait for all MongoDB pods to be Running and Ready
kubectl wait --for=condition=ready pod -l app=mongodb \
  -n <your-namespace> \
  --timeout=300s

Verify MongoDB is healthy:

kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongosh admin --eval "db.adminCommand('ping')"

You should see: { ok: 1 }

Step 3g: Verify MongoDB Service has endpoints

kubectl get endpoints mongodb-svc -n <your-namespace>

You should see the MongoDB pod’s IP address listed. If endpoints are empty, the service selector isn’t matching the pod labels correctly.

Step 4: Restore Your Backup Data

Step 4a: Retrieve MongoDB connection details

MONGO_PASSWORD=$(kubectl get secret mongodb-<release-name>-password \
  -n <your-namespace> -o jsonpath='{.data. password}' | base64 -d)

echo "MongoDB URI:"
echo "mongodb://rocketchat: ${MONGO_PASSWORD}@mongodb-0.mongodb-svc.<your-namespace>.svc.cluster. local:27017/rocketchat? authSource=rocketchat&replicaSet=mongodb"

Save this URI - you’ll need it in the next steps.

Step 4b: Restore your data to the new MongoDB

Once the new MongoDB instance is running and ready, restore your backup:

# Copy your backup into one of the MongoDB pods
kubectl cp ./mongodb-backup <your-namespace>/mongodb-0:/tmp/backup

# Restore the data using mongorestore
kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongorestore --uri="mongodb://rocketchat:<password>@mongodb-0.mongodb-svc. <your-namespace>.svc.cluster.local:27017/rocketchat" \
  /tmp/backup/rocketchat

Note: Adjust the connection string to match your MongoDB configuration (username, password, namespace, etc.)

Verify the restore was successful:

kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongosh -u rocketchat -p '<password>' --authenticationDatabase rocketchat \
  --eval "use rocketchat; show collections"

You should see your collections (workspaces, users, subscriptions, messages, etc.) restored.

Step 5: Upgrade Rocket.Chat with External MongoDB

Now upgrade the Rocket.Chat Helm chart to use the external MongoDB instance:

Step 5a: Upgrade the Rocket.Chat Helm chart

# Update your Helm repository
helm repo update

# Upgrade the Rocket.Chat Helm chart with the external MongoDB URI
# IMPORTANT: Include ALL your existing helm values (host, ingress, image tag, NATS config, etc.)
# along with the new MongoDB configuration
helm upgrade <release-name> rocketchat/rocketchat -n <your-namespace> \
  --set host=<your-host> \
  --set ingress.enabled=<true-or-false> \
  --set nats.cluster.name=<your-nats-cluster-name> \
  --set image.tag=<your-version> \
  --set mongodb.enabled=false \
  --set externalMongodbUrl="mongodb://rocketchat:${MONGO_PASSWORD}@mongodb-0.mongodb-svc.<your-namespace>.svc.cluster.local:27017/rocketchat?authSource=rocketchat&replicaSet=mongodb"

:warning: Critical: You MUST include all your existing Rocket.Chat configuration values in the helm upgrade command. If you omit values like host, ingress.enabled, nats.cluster.name, or image.tag, they will revert to chart defaults and may break your deployment. Use helm get values <release-name> -n <your-namespace> to see your current values.

The upgrade will:

  1. Disable the built in insecure and outdate bitnami mongodb
  2. Configure Rocket.Chat to connect to your new external MongoDB instance you deployed using the mongodb chart
  3. Start Rocket.Chat with the connection to the external MongoDB replicaset

Step 5b: Scale services back up

# Scale the main Rocket.Chat deployment back to 1 replica
kubectl scale deployment <release-name>-rocketchat -n <your-namespace> --replicas=1

# Scale all microservices back to 1 replica
kubectl scale deployment -n <your-namespace> \
  <release-name>-account \
  <release-name>-authorization \
  <release-name>-ddp-streamer \
  <release-name>-presence \
  --replicas=1

Wait for Rocket.Chat to be ready:

kubectl rollout status deployment/<release-name>-rocketchat \
  -n <your-namespace> \
  --timeout=300s

Step 6: Verify the Migration

Once the upgrade completes, verify that everything is working correctly:

# Check all pods are running
kubectl get pods -n <your-namespace>

# Check Rocket.Chat logs to confirm it's started and connected to MongoDB
kubectl logs deployment/<release-name>-rocketchat -n <your-namespace> | grep -A 15 "SERVER RUNNING"

You should see output like:

+----------------------------------------------+
|                SERVER RUNNING                |
+----------------------------------------------+
|                                              |
|  Rocket.Chat Version: 8.0.1                  |
|       NodeJS Version: 22.16.0 - arm64        |
|      MongoDB Version: 8.2.3                  |
|       MongoDB Engine:  unknown                |
|             Platform: linux                  |
|         Process Port: 3000                   |
|             Site URL: http://localhost:3000  |
|          Commit Hash: 7137ec80f3             |
|        Commit Branch: HEAD                   |
|                                              |
+----------------------------------------------+

This confirms Rocket.Chat has successfully connected to MongoDB and is ready.

Additional verification:

# Verify MongoDB is healthy and replicating
kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongosh admin --eval "rs.status()"

Connect to Rocket.Chat web interface

You’ll likely be presented with this pop up:

Be sure to click Configuration Update.


:clipboard: Troubleshooting

MongoDB operator pod not starting

kubectl logs deployment/mongodb-kubernetes-operator -n <your-namespace>
kubectl describe deployment mongodb-kubernetes-operator -n <your-namespace>

MongoDB pods not starting

kubectl logs mongodb-0 -n <your-namespace>
kubectl describe mongodbcommunity mongodb -n <your-namespace>

Rocket.Chat can’t connect to MongoDB

# Verify MongoDB service is accessible
kubectl get svc -n <your-namespace> | grep mongodb

# Test connection from a debug pod
kubectl run -it --rm debug --image=mongo:8.2.3 --restart=Never -n <your-namespace> -- \
  mongosh "mongodb://rocketchat:<password>@mongodb-0.mongodb-svc.<your-namespace>. svc.cluster.local:27017/rocketchat?authSource=rocketchat"

# Check Rocket.Chat logs for connection errors
kubectl logs deployment/<release-name>-rocketchat -n <your-namespace>

Persistent Volume issues

kubectl get pvc -n <your-namespace>
kubectl describe pvc <pvc-name> -n <your-namespace>

Data didn’t restore correctly

  • Verify the backup wasn’t corrupted: ls -la ./mongodb-backup
  • Check MongoDB logs for restore errors: kubectl logs mongodb-0 -n <your-namespace>
  • Verify you have the correct credentials and authentication database
  • Try a test restore to a different database first: mongorestore --uri="..." --nsInclude="backup.*" /tmp/backup

Old Bitnami MongoDB pod still exists

  • The old MongoDB pod should be automatically removed during the Helm upgrade
  • If it persists, check for any remaining PVCs: kubectl get pvc -n <your-namespace>
  • Manually delete old PVCs if needed (after confirming backup): kubectl delete pvc <old-pvc-name> -n <your-namespace>

:counterclockwise_arrows_button: Common Operations After Migration

Take a backup

kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongodump --uri="mongodb://admin: <password>@mongodb-0.mongodb-svc.<your-namespace>. svc.cluster.local:27017/admin" \
  --out /tmp/backup

kubectl cp <your-namespace>/mongodb-0:/tmp/backup ./mongodb-backup-$(date +%Y%m%d)

Restore a backup

# Copy your backup into one of the MongoDB pods
kubectl cp ./mongodb-backup <your-namespace>/mongodb-0:/tmp/backup

# Restore the data using mongorestore
kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongorestore --uri="mongodb://rocketchat:<password>@mongodb-0.mongodb-svc.<your-namespace>.svc. cluster.local:27017/rocketchat" \
  /tmp/backup/rocketchat

Update MongoDB version

kubectl patch mongodbcommunity mongodb -n <your-namespace> \
  --type='json' -p='[{"op": "replace", "path": "/spec/version", "value": "8.2.4"}]'

Check MongoDB replica set status

kubectl exec -it mongodb-0 -n <your-namespace> -- \
  mongosh admin --eval "rs.status()"

:books: Additional Resources


Getting Help

If you encounter issues during the migration:

Aaron, what about docker?

As per this:

1 Like