Setting up MongoDB with replicas for local development

Advocate for better developer's productivity and experience
Documenting my learnings and sharing it
Search for a command to run...

Advocate for better developer's productivity and experience
Documenting my learnings and sharing it
No comments yet. Be the first to comment.
Background Recently, I redesigned my team's pipeline running on a multi-module Maven monorepo using GitLab CI. It wasn't that the previous setup was broken, but my team faced a few persistent issues t
Background At work, thereās some test written where I wanted to query the database (repository) after mockMvc request has been made to verify the result. This is a very simple illustration of what it looks like. @SpringBootTest @AutoConfigureMockMvc ...

Context I recently came across TaskFile and wanted to use it to automate some of my workflows, which underlying invokes PowerShell commands. However, I faced several errors while doing so, and this post is to reflect on it, and hopefully help myself ...

Problem I was always out of disk space in my C drive, and even though I clear my stuff often, I notice that my space is never reclaimed, instead, it kept going down. I used WizTree to view which file is taking up my disk space, and I noticed this No...

It's been a long time coming, but I finally came around to set up MongoDB with replicas for local development.
TLDR; clone the repository, run docker compose up -d, and you are good to go!
If you want to know more, continue to read below.
Running MongoDB with replicas locally is useful for a number of reason, but for me, I need it to run Debezium for Change-Data-Capture use case which requires it.
I have tried a number of solutions online, and was never able to succeed for some reason, although I did come close to it a couple of times. In any case, I would like to jot down some notes for the future me.
A keyfile contains a shared password used as challenge and response for internal authentication.
To generate it, run
openssl rand -base64 756 > mongo-replica.key
To run it
docker compose up -d
This will start up 4 containers;
mongo-1: PRIMARY
mongo-2: SECONDARY
mongo-3: ARBITER
mongo-setup: SETUP replicas via setup.sh
The default username is admin and password is password as defined under MONGO_INITDB_ROOT_USERNAME and MONGO_INITDB_ROOT_PASSWORD environment variable respectively. And using mgrs as the replicaset name.
However, do ensure that you do not have another running instance of MongoDB (at least not on 27017 port). Personally, I have issue connecting to replicas when another instance is running. (I haven't dived deep into why yet)
Please wait until mongo-setup container is shut down before connecting to the MongoDB instance.
Once the setup is done, we could verify to see if everything is set up as we wanted (i.e. replicas).
# exec into the container and running bash
docker exec -it mongo-1 bash
# connect to mongodb
mongosh --host mongo-1:27017 --username admin --password password
# checking the replica set status
rs.status()
The output will look something along the following
{
set: 'mgrs',
date: ISODate('2024-01-13T08:57:45.161Z'),
// omitted
members: [
{
_id: 1,
name: 'mongo-1:27017',
health: 1,
state: 1,
stateStr: 'PRIMARY',
// omitted
},
{
_id: 2,
name: 'mongo-2:27017',
health: 1,
state: 2,
stateStr: 'SECONDARY',
// omitted
},
{
_id: 3,
name: 'mongo-3:27017',
health: 1,
state: 7,
stateStr: 'ARBITER',
// omitted
}
],
ok: 1,
'$clusterTime': {
clusterTime: Timestamp({ t: 1705136259, i: 1 }),
signature: {
hash: Binary.createFromBase64('62HGgCSWnDEzK2Ke+7HOtI8gz00=', 0),
keyId: Long('7323504381729439750')
}
},
operationTime: Timestamp({ t: 1705136259, i: 1 })
}
The following URI would work
mongodb://admin:password@localhost:27017/?authMechanism=DEFAULT&authSource=admin&directConnection=true

Direct Connection option is selected
This is a little bit more tricky. You will need to add the following to your hosts file located in C:\Windows\System32\drivers\etc directory.
127.0.0.1 mongo-1 mongo-2 mongo-3
Make sure you have administrator rights to do so. Once done, the following URI would work.
mongodb://admin:password@mongo-1:27017,mongo-2:27017,mongo-3:27017/?authMechanism=DEFAULT&authSource=admin

If you are using Spring Boot, you can use the following URI to connect as well
spring:
data:
mongodb:
# either one would work
# without replica
uri: mongodb://admin:password@localhost:27017/bwgjoseph?authSource=admin
# with replica
uri: mongodb://admin:password@mongo-1:27017,mongo-2:27017,mongo-3:27017/bwgjoseph?authSource=admin&replicaSet=mgrs
In this article, I have talked about some of the things to note, such as the keyfile and how to connect to the replica set via Mongo Compass or in your Spring Boot application.
I hope this is useful and providing some context on why certain setup/configuration is required rather than just copying the scripts and hoping it will work for you.
As usual, the full source code is available on GitHub