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

> Automate MongoDB sharded cluster initialization with Docker Compose entrypoint scripts. Learn how scripts form replica sets and add shards seamlessly without manual steps.

- Repository: [Jin/mongodb-cluster-docker-compose](https://github.com/minhhungit/mongodb-cluster-docker-compose)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/entrypoint-configserver.sh)
- **`shard01-a`, `shard02-a`, `shard03-a`**: Primary nodes for each shard that execute [`entrypoint-shard01.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/entrypoint-shard01.sh), [`entrypoint-shard02.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/entrypoint-shard02.sh), and [`entrypoint-shard03.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard01.sh):

```bash
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:

```bash
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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard01.sh):

```bash
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:

```bash
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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard02.sh) and [`scripts/entrypoint-shard03.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard03.sh) for their respective replica sets, while [`scripts/entrypoint-configserver.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-configserver.sh) handles the config server replica set (`rs-config-server`).

### Configuring the Query Router

The router entrypoint ([`scripts/entrypoint-route.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-route.sh)) performs the final orchestration. It first polls the config server replica set until a primary is elected:

```bash
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:

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

```

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

```bash
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`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/docker-compose.yml) | Defines services, networks, volumes, and mounts entrypoint scripts |
| [`scripts/entrypoint-shard01.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard01.sh) | Initializes the `rs-shard-01` replica set (shard 01 primary) |
| [`scripts/entrypoint-shard02.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard02.sh) | Initializes the `rs-shard-02` replica set (shard 02 primary) |
| [`scripts/entrypoint-shard03.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-shard03.sh) | Initializes the `rs-shard-03` replica set (shard 03 primary) |
| [`scripts/entrypoint-configserver.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/scripts/entrypoint-configserver.sh) | Initializes the `rs-config-server` replica set |
| [`scripts/entrypoint-route.sh`](https://github.com/minhhungit/mongodb-cluster-docker-compose/blob/main/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.