Setting Up a MongoDB Replica Set with Docker for Change Streams
version: '3.8'
services:
node1:
image: mongo:latest
container_name: mongo_r1
ports:
- 27017:27017
volumes:
- vol_node1:/data/db
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
node2:
image: mongo:latest
container_name: mongo_r2
ports:
- 27018:27017
volumes:
- vol_node2:/data/db
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
node3:
image: mongo:latest
container_name: mongo_r3
ports:
- 27019:27017
volumes:
- vol_node3:/data/db
command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
volumes:
vol_node1:
vol_node2:
vol_node3:
Save this configuration as docker-compose.yml and launch the stack:
docker-compose up -d
Once all three containers are running, attach to the mongosh shell on the first node:
docker exec -it mongo_r1 mongosh
Initialize the replica set with the following command:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo_r1:27017" },
{ _id: 1, host: "mongo_r2:27017" },
{ _id: 2, host: "mongo_r3:27017" }
]
})
After successful initialization, the shell prompt changes to indicate the primary node, e.g., rs0 [direct: primary]. You can verify the set status with rs.status() and inspect the running containers in Docker Desktop.
Accessing the Replica Set as PRIMARY
When connecting via mongosh or a GUI tool like MongoDB Compass, use the full replica set connection string:
mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0
If you enter the mongosh shell and see a secondary prompt, press Enter after the initial connection attempt to be recognized as the primary node.
Creating Users
All user management must occur on the admin database. Switch to it first:
use admin
Then create an administrative user:
db.createUser({
user: "rootAdmin",
pwd: "securePassword",
roles: ["root"]
})
Authenticate immediately:
db.auth("rootAdmin", "securePassword")
A response of { ok: 1 } confirms successful authentication.
Working with Change Streams
With the replica set deployed, Node.js applications can open change streams against collections:
const { MongoClient } = require('mongodb');
const uri = 'mongodb://rootAdmin:securePassword@localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0&authSource=admin';
async function watchChanges() {
const client = new MongoClient(uri);
await client.connect();
const collection = client.db('exampleDb').collection('exampleColl');
const changeStream = collection.watch();
changeStream.on('change', (change) => {
console.log('Change event:', change);
});
}
watchChanges().catch(console.error);
Always mount dedicated Docker volumes for each node to prevent premature container termination and data loss.