How to Automatically Initialize a MongoDB Sharded Cluster with Docker Compose Entrypoint Scripts

A MongoDB sharded cluster is automatically initialized by Bash entrypoint scripts that start mongod processes, wait for peer discovery, execute rs.initiate() to form replica sets, and finally launch mongos with sh.addShard() to register shards—all orchestrated through docker-compose.yml without manual intervention.

The minhhungit/mongodb-cluster-docker-compose repository demonstrates a fully automated approach to deploying a production-ready MongoDB sharded cluster using Docker Compose. By leveraging custom entrypoint scripts mounted into each container, the topology bootstraps itself from a cold start, eliminating the need for manual replica set configuration or shard registration via the MongoDB shell.

Container Startup Order and Service Architecture

The docker-compose.yml defines distinct services for config servers, shard nodes, and query routers. Each service mounts a specific entrypoint script from the scripts/ directory that handles initialization logic:

  • configsvr01: Boots the config server replica set (rs-config-server) using entrypoint-configserver.sh
  • shard01-a, shard02-a, shard03-a: Primary nodes for each shard that execute entrypoint-shard01.sh, entrypoint-shard02.sh, and entrypoint-shard03.sh respectively to initiate rs-shard-01, rs-shard-02, and rs-shard-03
  • shard0X-b and shard0X-c: Secondary members that start mongod without custom entrypoints, joining the replica set initiated by their respective -a nodes
  • router01: Executes entrypoint-route.sh to launch mongos and register all shards via sh.addShard()

Entrypoint Script Mechanics

The initialization logic follows a consistent pattern across all entrypoint scripts: start the MongoDB process, verify peer connectivity, and execute replica set commands.

Starting MongoDB Processes

Each script launches mongod in the background with role-specific flags. For shard nodes in scripts/entrypoint-shard01.sh:

mongod --shardsvr --replSet rs-shard-01 --port 27017 --bind_ip_all &

Config servers use --configsvr instead of --shardsvr, while the router entrypoint starts mongos after validation checks.

Waiting for Peer Discovery

Before initiating replica sets, scripts verify local readiness and peer availability through polling functions. The check_mongo_ready helper pings the local instance:

until check_mongo_ready 127.0.0.1; do
  sleep 2
done

For replica set initialization, the primary node waits for its secondary peers. From scripts/entrypoint-shard01.sh:

for host in shard01-b shard01-c; do
  until check_mongo_ready "$host"; do
    sleep 2
  done
done

Initializing Replica Sets

Once all members are reachable, the primary node executes rs.initiate() via mongosh. The script constructs a JavaScript object defining the replica set configuration:

mongosh --eval '
  rs.initiate({
    _id: "rs-shard-01",
    members: [
      { _id: 0, host : "shard01-a:27017" },
      { _id: 1, host : "shard01-b:27017" },
      { _id: 2, host : "shard01-c:27017" }
    ]
  })
'

This pattern repeats in scripts/entrypoint-shard02.sh and scripts/entrypoint-shard03.sh for their respective replica sets, while scripts/entrypoint-configserver.sh handles the config server replica set (rs-config-server).

Configuring the Query Router

The router entrypoint (scripts/entrypoint-route.sh) performs the final orchestration. It first polls the config server replica set until a primary is elected:

until mongosh --host rs-config-server/configsvr01:27017,configsvr02:27017,configsvr03:27017 \
     --eval 'rs.status().members.some(m => m.stateStr === "PRIMARY")' | grep -q true; do
  sleep 5
done

After verifying all shard primaries are available, it starts mongos pointing to the config server replica set:

mongos --configdb rs-config-server/configsvr01:27017,configsvr02:27017,configsvr03:27017 --port 27017 --bind_ip_all &

Finally, it registers each shard using sh.addShard():

mongosh --eval 'sh.addShard("rs-shard-01/shard01-a:27017")'
mongosh --eval 'sh.addShard("rs-shard-02/shard02-a:27017")'
mongosh --eval 'sh.addShard("rs-shard-03/shard03-a:27017")'

End-to-End Initialization Flow

When you execute docker compose up -d from the repository root, the following sequence occurs:

  1. Concurrent container startup: Docker Compose creates all config servers, shard nodes, and the router simultaneously
  2. Shard replica set formation: Each shard0X-a container starts mongod, waits for its -b and -c peers, then executes rs.initiate() to form rs-shard-0X
  3. Config server initialization: configsvr01 performs the same polling and initiation for the rs-config-server replica set
  4. Router activation: router01 polls until all replica sets report a PRIMARY member, starts mongos, and executes sh.addShard() for each shard
  5. Steady state: All entrypoint scripts finish but keep the MongoDB processes running via wait $MONGO_PID, leaving the cluster operational

Key Files and Scripts

File Purpose
docker-compose.yml Defines services, networks, volumes, and mounts entrypoint scripts
scripts/entrypoint-shard01.sh Initializes the rs-shard-01 replica set (shard 01 primary)
scripts/entrypoint-shard02.sh Initializes the rs-shard-02 replica set (shard 02 primary)
scripts/entrypoint-shard03.sh Initializes the rs-shard-03 replica set (shard 03 primary)
scripts/entrypoint-configserver.sh Initializes the rs-config-server replica set
scripts/entrypoint-route.sh Launches mongos and executes sh.addShard() for all shards

Summary

  • Entrypoint scripts automate the entire MongoDB sharded cluster initialization by handling replica set creation and shard registration without manual intervention.
  • Each shard primary node (shard01-a, shard02-a, shard03-a) runs a dedicated script that polls for peer availability before calling rs.initiate().
  • The config server uses an identical pattern to establish the rs-config-server replica set that stores cluster metadata.
  • The router container waits for all replica sets to elect primaries, starts mongos, and attaches shards using sh.addShard().
  • All scripts are idempotent, allowing the cluster to restart safely without re-initialization errors.

Frequently Asked Questions

What is the purpose of the entrypoint scripts in this MongoDB cluster?

The entrypoint scripts serve as automated bootstrap agents that transform individual MongoDB containers into a cohesive sharded cluster. They execute the necessary rs.initiate() commands to form replica sets and sh.addShard() commands to register shards with the query router, eliminating the need for manual configuration after containers start.

How do the scripts ensure the correct startup order without Docker Compose depends_on limitations?

Rather than relying solely on Docker Compose's depends_on (which only controls container start order, not service readiness), the scripts implement active polling loops. They use mongosh with --eval to check rs.status() or connection readiness, retrying until peer containers are fully initialized and ready to accept replica set configuration commands.

Can I add additional shards to the cluster after the initial Docker Compose deployment?

Yes, you can add new shards by creating new replica sets using the same entrypoint pattern (start mongod with --shardsvr, run rs.initiate()), then connecting to the router container and executing sh.addShard() manually. The existing scripts demonstrate the exact commands needed to register new shards with the running mongos process.

Are the entrypoint scripts safe to run if the cluster restarts?

Yes, the scripts are designed to be idempotent. If a replica set is already initialized, the rs.initiate() command returns an error that the script handles gracefully, and the router's sh.addShard() commands similarly tolerate existing shard registrations. This ensures that restarting the Docker Compose stack does not corrupt the cluster topology or fail with duplicate initialization errors.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →