DEV Community

Cover image for How To Setup MongoDB Like a Pro
Pankaj Gupta
Pankaj Gupta

Posted on • Edited on

How To Setup MongoDB Like a Pro

Introduction

I started my career 6 years ago as a Frontend Engineer. We had mongoDB as our main database. Although I was a FE, I have always been fascinated by how the fancier things like replication, caching actually works. I was too afraid to try it, hoping I would break the running things on my system and would have to spend a lot of time fixing that. The fear stopped me from trying a lot of things I wanted to try. Today we will be trying one of those things and break the shackles.

We will be going through setting up mongoDB on your local machine and running multiple instance of it to setup replicaSet and how to add new machines and remove machine and all that, this skill can be directly transffered to a cloud based setup as well.

Installing MongoDB(community edition - 6.0)

Installing MongoDB DB can be varied based on your local machine. You can follow the steps below if you are using Ubuntu 22.04 otherwise you can follow this guide here.

MongoDB only supports the 64-bit versions of these platforms. To determine which Ubuntu release your host is running, run the following command on the host's terminal:

cat /etc/lsb-release
Enter fullscreen mode Exit fullscreen mode
  • Import the public key used by the package management system
# install gnupg and curl if they are not already available
sudo apt-get install gnupg curl

# import the MongoDB public GPG key
curl -fsSL https://pgp.mongodb.com/server-6.0.asc | \
   sudo gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg \
   --dearmor
Enter fullscreen mode Exit fullscreen mode
  • Create a list file for MongoDB
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
Enter fullscreen mode Exit fullscreen mode
  • Reload local package database
sudo apt-get update
Enter fullscreen mode Exit fullscreen mode
  • Install the MongoDB Package
sudo apt-get install -y mongodb-org
Enter fullscreen mode Exit fullscreen mode

If there was no error, you would have successfully installed mongod and mongosh CLI Tools.

I ran into some issues, I will mention the StackOverflow links here which helped me with the issues:

  • Unable to locate package mongodb-org
    • You can try to install the package, mongodb instead of monggodb-org. It is the unofficially package.
    • I was installing the version 7 which is the latest, but I chose to used the previous version and the issue was solved.

Getting comfortable with mongod and mongosh

If you are running a Mac, you'll most likely be using brew to install all the background services and running them. You can use the similar commands in Ubuntu as well using systemd to run the services in daemon mode or in background.

Starting the service

sudo systemctl start mongod
Enter fullscreen mode Exit fullscreen mode

This should start the mongod on port 27017, If you run into any issues, you'll have to debug the issue.

Stopping the service

sudo systemctl stop mongod
Enter fullscreen mode Exit fullscreen mode

Restarting the service

sudo systemctl restart mongod
Enter fullscreen mode Exit fullscreen mode

Connecting to a mongod instance with mongosh

mongosh
Enter fullscreen mode Exit fullscreen mode

You'll be taken into the shell and you'll be connected to test db by default and you can experiment all you want with it.


Running mongod in foreground

You can run mongod on the foreground as well. No matter where you run it from background or foreground, it knows where to store the data, it knows where to write the logs, it knows what port to start on. How does it know? The secret is /etc/mongod.conf file.

Now if you cat /etc/mongod.conf file, you'll get something like this:

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
#  engine:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1


# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp:
Enter fullscreen mode Exit fullscreen mode

For the beginners, there are 2 important things mentioned in this file:

  • storage.dbPath
  • net.port

storage.dbPath

It refers to a directory, where mongo will be storing all the data.

net.port

It refers to a port, on which the mongod will start.


It is because of this conf file, you can't start multiple mongod instance. You can try starting two mongod instances on two terminal windows and it'll give a port error, mentioning the port is already occupied.

The good thing is now we know what are the keys and we have an option to overwrite these keys with our values. Lets explore that option.


Starting mongosh with different arguments

When you start mongod, it picks the default port from /etc/mongod.conf file, which is 27017. In order to start the mongod on a different port, either you can update the mongod.conf file to use a different port or you can provide command line argument like this:

mongod --port 27019
Enter fullscreen mode Exit fullscreen mode

Running this command you'll be able to start the mongod on port 27019.

Keep in mind to connect to this instance using mongosh, you'll need to pass the port as well using --port

It also picks up a default location of the db. You can pass in the dbPath to override that as well. Before we do that lets make a directory call mongo-dbs and create db1, db2 and db3 directory inside of it and start 3 different instance of mongo on different ports and dbs separate from each other.

mkdir mongo-dbs
cd mongo-dbs
mkdir db1
mkdir db2
mkdir db3
Enter fullscreen mode Exit fullscreen mode

Now in the first terminal, type in:

mongod --dbpath ./db1 --port 27020
Enter fullscreen mode Exit fullscreen mode

In the second terminal type in:

mongod --dbpath ./db2 --port 27021
Enter fullscreen mode Exit fullscreen mode

In the third terminal, type in:

mongod --dbpath ./db3 --port 27022
Enter fullscreen mode Exit fullscreen mode

Now you have three different instances of mongod running, you can connect to each of them using mongosh --port .


Replication

If you have made it this far in the blog, congratulations. Lets see how the replication works in mongodb and setup a master - slave - slave replication.

If you see the mongod.conf file, you'll see:

#replication:
Enter fullscreen mode Exit fullscreen mode

That means by default the mongod doesn't have any replication setup.

Inorder to setup mongod as replicas, we need to start it in a replication mode and give the replica a name. You can do that by:

mongod --dbpath ./db1 --port 27020 --replSet my_replica
Enter fullscreen mode Exit fullscreen mode

And you can start the other instances as well in the same manner keeping the name my_replica consistent.

Once all the instances are running choose which mongod you want as primary and log on to that instance with mongosh --port .

Now type in the command to initiate the replication:

rs.initiate()
Enter fullscreen mode Exit fullscreen mode

This should give an acknowledgement that the replication has been started. In order check the status of the replicaSet:

rs.status()
Enter fullscreen mode Exit fullscreen mode

It throw out something like this:

{
  set: 'myreplica',
  date: ISODate('2024-01-24T07:07:53.872Z'),
  myState: 1,
  term: Long('6'),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long('2000'),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {...},
  lastStableRecoveryTimestamp: Timestamp({ t: 1706080036, i: 1 }),
  electionCandidateMetrics: {...},
  electionParticipantMetrics: {...},
  members: [
    {
      _id: 0,
      name: 'localhost:27020',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 2800,
      optime: { ts: Timestamp({ t: 1706080066, i: 1 }), t: Long('6') },
      optimeDate: ISODate('2024-01-24T07:07:46.000Z'),
      lastAppliedWallTime: ISODate('2024-01-24T07:07:46.580Z'),
      lastDurableWallTime: ISODate('2024-01-24T07:07:46.580Z'),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1706078026, i: 1 }),
      electionDate: ISODate('2024-01-24T06:33:46.000Z'),
      configVersion: 5,
      configTerm: 6,
      self: true,
      lastHeartbeatMessage: ''
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1706080066, i: 1 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1706080066, i: 1 })
}

Enter fullscreen mode Exit fullscreen mode

If everything has worked for you till now, congratulations. Now we will be adding new members to this replicaSet. To add a new member:

rs.add('localhost:27021')
Enter fullscreen mode Exit fullscreen mode

This will also give an acknowledgement that a member has been added. Now if you check the status of the replicaSet:

rs.status()
Enter fullscreen mode Exit fullscreen mode

You have two members marked:

stateStr: 'PRIMARY' and the other as stateStr: 'SECONDARY'

Denoting the primary and the secondary instances. Secondary will also have one key

syncSourceHost: 'localhost:27020'

Denoting which instance it will sync the data from. In the similar fashion, you can add the last instance as a member of this replicaSet and check the status.

Now if you add any data in the primary member it'll automatically be synced to the secondary members.


Production Setup

We have learned a lot of stuff, and it can be very daunting to try this for the first time. Lets expand this knowledge and move from local to production.

We replicate data, to increase our availability, so if somehting happens to one instance other instances are running. Replicating data on same machine would mean if something wrong happens to the machine like power outage etc, the whole database would stop responding to requests.

So in production we have multiple machines, and we have update the mongod.conf file on each of the machine to setup replication.

Things to explore

I want you to explore:

  • What happens when you shut off a instance?
  • Suppose we have data in the instances already, and you add a blank member, what will happen.
  • What happens when a primary member is not working?

Top comments (0)