Skip to content

MongoDB

Deploy MongoDB on Kubernetes using the official mongo Docker image. Supports standalone single-instance, replica set for high availability, and sharded cluster for horizontal scalability.

Replica set keyFile must not change — rotating it breaks internal member authentication

Replica set members authenticate each other using a shared keyFile (auth.replicaSetKey). When the chart generates it, the Secret is retained and reused across upgrades and persistent-release removal. Rotating or regenerating this key after initialization will cause all replica set members to reject each other. Back up the generated Secret with the PVCs, or use auth.existingKeySecret when credentials are externally managed.

Auth credentials are set on first initialization only — they cannot be changed via values on upgrade

auth.rootPassword and user passwords defined in auth.users are written during the first container initialization (/docker-entrypoint-initdb.d/). Changing these values in a subsequent helm upgrade has no effect on the running container. To rotate credentials, connect to MongoDB directly using the mongo shell (db.updateUser() / db.changeUserPassword()).

Key Features

  • Three architectures — standalone, replica set, sharded cluster
  • Replica set HA — rs0 with configurable member count and optional arbiter
  • Sharded cluster — mongos routers, config servers, and data shards
  • Internal keyFile auth — replica set member authentication via shared secret
  • Upgrade-safe generated credentials — root credentials and keyFiles are retained with persistent data
  • Init scripts — .js and .sh files via /docker-entrypoint-initdb.d/
  • WiredTiger tuning — custom mongod.conf via config block
  • Prometheus exporter — percona/mongodb_exporter sidecar with ServiceMonitor
  • mongodump backup — scheduled S3 backup CronJob
  • Pinned upstream image — official MongoDB 9.0.4 patch release

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install my-mongo helmforge/mongodb -f values.yaml

OCI registry:

helm install my-mongo oci://ghcr.io/helmforgedev/helm/mongodb -f values.yaml

Deployment Examples

# values.yaml — MongoDB standalone (single instance)
architecture: standalone

auth:
  enabled: true
  rootUser: root
  existingSecret: mongodb-root-credentials # keys: mongodb-root-username, mongodb-root-password
  users:
    - username: appuser
      password: 'app-password'
      database: myapp
      roles:
        - { role: readWrite, db: myapp }

persistence:
  enabled: true
  size: 20Gi

config:
  storage:
    wiredTiger:
      engineConfig:
        cacheSizeGB: 1 # set to ~50% of available memory minus OS overhead

metrics:
  enabled: true
  serviceMonitor:
    enabled: true
# values.yaml — MongoDB replica set (3 members, HA)
architecture: replicaset

auth:
  enabled: true
  existingSecret: mongodb-root-credentials
  existingKeySecret: mongodb-replica-key # key: mongodb-replica-set-key (must not change)

replicaSet:
  name: rs0
  members: 3

persistence:
  enabled: true
  size: 50Gi

config:
  storage:
    wiredTiger:
      engineConfig:
        cacheSizeGB: 2

metrics:
  enabled: true
  serviceMonitor:
    enabled: true
# Connection string for replica set:
# mongodb://appuser:[email protected]:27017/myapp?replicaSet=rs0
# values.yaml — Replica set with arbiter (2 data members + 1 arbiter)
# Use when you want odd-number election votes without a 3rd data-bearing member
architecture: replicaset

auth:
  enabled: true
  existingSecret: mongodb-root-credentials
  existingKeySecret: mongodb-replica-key

replicaSet:
  name: rs0
  members: 2 # 2 data-bearing members; arbiter provides the 3rd vote

arbiter:
  enabled: true # lightweight pod: votes in elections but stores no data

persistence:
  enabled: true
  size: 50Gi
When to use an arbiter

An arbiter participates in elections but holds no data. Use it when you have an even number of data-bearing members to ensure a majority for elections. MongoDB recommends three data-bearing members when capacity permits because an arbiter does not add data redundancy and can affect majority write availability. The chart supports one arbiter with 2, 4, or 6 data-bearing members. See the official arbiter considerations.

# values.yaml — MongoDB sharded cluster (2 shards, 3 members each)
architecture: sharded

auth:
  enabled: false

sharded:
  mongos:
    replicaCount: 2 # query routing layer
    port: 27017
  configServer:
    replicaCount: 3 # cluster metadata (must be odd)
    persistence:
      size: 10Gi
  shards:
    count: 2 # number of shards
    membersPerShard: 3 # members per shard replica set
    persistence:
      size: 100Gi

config:
  storage:
    wiredTiger:
      engineConfig:
        cacheSizeGB: 4
Connect to a sharded cluster via mongos, not shard members directly

Always connect to the mongos service, not to individual shard replica set members. Shards should only be accessed directly for administrative operations.

Sharded auth requires operator bootstrap

The chart validates sharded mode as an unauthenticated lab topology. The official MongoDB container initializes MONGO_INITDB_ROOT_* as a standalone process, which conflicts with --configsvr and --shardsvr. Production sharded authentication requires an operator-managed bootstrap flow outside the chart’s automatic root-user path.

Configuration Reference

Image

Parameter Type Default Description
image.repository string docker.io/library/mongo MongoDB image.
image.tag string "9.0.4" Image tag.

Authentication

Parameter Type Default Description
auth.enabled boolean true Enable MongoDB --auth flag.
auth.rootUser string root Root username (MONGO_INITDB_ROOT_USERNAME).
auth.rootPassword string "" Root password. Auto-generated and retained if empty. Set only on first deployment.
auth.existingSecret string "" Existing secret. Keys: mongodb-root-username, mongodb-root-password.
auth.replicaSetKey string "" KeyFile for internal replica set auth. Auto-generated and retained if empty.
auth.existingKeySecret string "" Existing secret with keyFile. Key: mongodb-replica-set-key.
auth.users array [] Additional users to create on first startup.

Architecture

Parameter Type Default Description
architecture string standalone standalone, replicaset, or sharded.
replicaSet.name string rs0 Replica set name.
replicaSet.members integer 3 Number of data-bearing replica set members.
arbiter.enabled boolean false Add one non-data-bearing voting member in replica set mode.
arbiter.resources object {} CPU and memory requests/limits for the arbiter mongod container.

Sharded Cluster

Parameter Type Default Description
sharded.mongos.replicaCount integer 2 Number of mongos router pods.
sharded.configServer.replicaCount integer 3 Config server members (must be odd).
sharded.configServer.persistence.size string 8Gi Config server PVC size.
sharded.shards.count integer 2 Number of shards.
sharded.shards.membersPerShard integer 3 Replica set members per shard.
sharded.shards.persistence.size string 16Gi Data PVC size per shard member.

Persistence and Configuration

Parameter Type Default Description
persistence.enabled boolean true Enable PVC for data (StatefulSet volumeClaimTemplate).
persistence.size string 8Gi PVC size per member.
config object {} Custom mongod.conf content (WiredTiger cache, profiling).
port integer 27017 MongoDB listen port.
initdbScripts object {} .js/.sh init scripts via /docker-entrypoint-initdb.d/.
Set WiredTiger cache to ~50% of available memory

MongoDB’s WiredTiger engine defaults to 50% of available RAM for its cache. Always set resources.limits.memory and tune config.storage.wiredTiger.engineConfig.cacheSizeGB explicitly to avoid OOM kills. For example, a pod with 4 GiB memory limit should use cacheSizeGB: 1.5 (leaving headroom for OS and index overhead).

Service

Parameter Type Default Description
service.type string ClusterIP Client Service type.
service.port integer 27017 Client Service port.
service.ipFamilyPolicy string "" Service IP family policy: SingleStack, PreferDualStack, or RequireDualStack.
service.ipFamilies array [] Optional Service IP family override.

External Secrets

Use External Secrets when root credentials are owned by an external secret manager. Set auth.existingSecret to the same target Secret name so the StatefulSet consumes the synchronized Secret instead of rendering a competing chart-managed Secret.

Parameter Type Default Description
externalSecrets.enabled boolean false Render an ExternalSecret for MongoDB credentials.
externalSecrets.refreshInterval string 1h ExternalSecret refresh interval.
externalSecrets.secretStoreRef.name string "" SecretStore or ClusterSecretStore name.
externalSecrets.secretStoreRef.kind string SecretStore Secret store kind.
externalSecrets.data array [] Data mappings for root credentials and backup secrets.

Metrics

Parameter Type Default Description
metrics.enabled boolean false Deploy percona/mongodb_exporter sidecar.
metrics.port integer 9216 Exporter metrics port.
metrics.serviceMonitor.enabled boolean false Create Prometheus ServiceMonitor resource.

When auth.enabled: false, the exporter now connects without root credentials using mongodb://localhost:27017/admin. With authentication enabled, it keeps using the root credentials from the chart-managed or existing secret.

Pod Security

Parameter Type Default Description
automountServiceAccountToken boolean false Mount a Kubernetes API token in pods and jobs.
podSecurityContext.fsGroup integer 999 Filesystem group used for MongoDB data volumes.
podSecurityContext.seccompProfile.type string RuntimeDefault Seccomp profile applied to MongoDB pods and jobs.

Backup

Backup uses mongodump (not pg_dump). All databases are dumped and archived.

Parameter Type Default Description
backup.enabled boolean false Enable scheduled mongodump S3 backup.
backup.schedule string "0 3 * * *" Cron schedule.
backup.s3.endpoint string "" S3-compatible endpoint URL.
backup.s3.bucket string "" Target bucket name.
backup.s3.existingSecret string "" Existing secret with S3 credentials.
backup.database.mongoDumpArgs string "" Extra mongodump arguments.
extraManifests array [] Extra Kubernetes manifests.

Upgrade Notes

MongoDB 9.0.4 is a patch in the 9.0 rapid-release line. Before upgrading from 8.3, take a tested backup and confirm every member reports featureCompatibilityVersion: "8.3". Follow the topology-specific upstream procedure, then raise FCV to 9.0 only after all members are healthy and rollback is no longer required. Review the MongoDB 9.0 release notes. The chart reuses generated root credentials and replica set keyFiles across helm upgrade --reset-values and helm upgrade --reuse-values, and retains them when a persistent release is removed. Back up the Secrets together with the PVCs. Rotate credentials with MongoDB administrative commands and a coordinated Secret update instead of changing initialization values.

StatefulSet claim-template sizes are immutable. The chart preserves each installed template size during upgrades, including --reset-values, so a custom-size installation does not fail when defaults are reapplied. Resize the bound PVC through the storage class workflow; changing persistence.size alone does not resize an existing claim or change the size used for PVCs created by future scale-up. Before adding members after expanding existing PVCs, confirm that the retained claim-template size can hold a new member’s initial synchronization.

Switching from standalone to replicaset requires a full dump and restore

MongoDB cannot automatically convert a standalone instance to a replica set with data. You must:

  1. Dump the data with mongodump.
  2. Deploy the chart in replicaset mode.
  3. Restore data with mongorestore.

Enabling or disabling arbiter.enabled reconciles the arbiter through the post-upgrade hook. Increasing replicaSet.members adds missing members. Reducing it does not remove data-bearing members from MongoDB; follow MongoDB’s member-removal procedure before scaling down the StatefulSet.

When arbiter reconciliation would change MongoDB’s implicit default write concern, the hook preserves the currently effective value (w: 1 or majority) by promoting it to a global default. Existing operator-managed global defaults are left unchanged. MongoDB 5.0 and newer do not allow a global default write concern to be unset after it is established. See the official setDefaultRWConcern documentation.

More Information