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) usingentrypoint-configserver.shshard01-a,shard02-a,shard03-a: Primary nodes for each shard that executeentrypoint-shard01.sh,entrypoint-shard02.sh, andentrypoint-shard03.shrespectively to initiaters-shard-01,rs-shard-02, andrs-shard-03shard0X-bandshard0X-c: Secondary members that startmongodwithout custom entrypoints, joining the replica set initiated by their respective-anodesrouter01: Executesentrypoint-route.shto launchmongosand register all shards viash.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:
- Concurrent container startup: Docker Compose creates all config servers, shard nodes, and the router simultaneously
- Shard replica set formation: Each
shard0X-acontainer startsmongod, waits for its-band-cpeers, then executesrs.initiate()to formrs-shard-0X - Config server initialization:
configsvr01performs the same polling and initiation for thers-config-serverreplica set - Router activation:
router01polls until all replica sets report a PRIMARY member, startsmongos, and executessh.addShard()for each shard - 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 callingrs.initiate(). - The config server uses an identical pattern to establish the
rs-config-serverreplica set that stores cluster metadata. - The router container waits for all replica sets to elect primaries, starts
mongos, and attaches shards usingsh.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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →