<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Toby Johnson on Medium]]></title>
        <description><![CDATA[Stories by Toby Johnson on Medium]]></description>
        <link>https://medium.com/@toby-j?source=rss-69e0a031b1af------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*_yBE_PfYYRIhXVK3ibe9nQ.png</url>
            <title>Stories by Toby Johnson on Medium</title>
            <link>https://medium.com/@toby-j?source=rss-69e0a031b1af------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 21 Jun 2026 15:52:38 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@toby-j/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Deploying a MongoDB Replica set]]></title>
            <link>https://medium.com/@toby-j/deploying-a-mongodb-replica-set-8c028cb02a07?source=rss-69e0a031b1af------2</link>
            <guid isPermaLink="false">https://medium.com/p/8c028cb02a07</guid>
            <category><![CDATA[ubuntu]]></category>
            <category><![CDATA[mongodb-tutorial]]></category>
            <category><![CDATA[mongodb]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[windows]]></category>
            <dc:creator><![CDATA[Toby Johnson]]></dc:creator>
            <pubDate>Wed, 13 Mar 2024 12:28:50 GMT</pubDate>
            <atom:updated>2024-03-13T13:15:12.493Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*g9C3d43RqufsGKIC" /><figcaption>Photo by <a href="https://unsplash.com/@oskarssylwan?utm_source=medium&amp;utm_medium=referral">Oskars Sylwan</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>For testing and development, a standalone MongoDB instance offers a quick and easy setup. However, it lacks replication and high availability; this makes it unsuitable for a production environment. Or as MongoDB themselves put it:</p><p><strong>Disclaimer:</strong> I’ve written and tested this tutorial for Windows Server 2016 and Ubuntu 22.04.4 LTS. However, I’m confident it’ll work just fine on versions close to these.</p><p>This tutorial does <strong>not</strong> involve Atlas. This is for MongoDB Enterprise or Community Edition servers.</p><blockquote><strong>Do not</strong> use these deployments for production systems as they lack replication and high availability. For all production deployments use replica sets.</blockquote><p>Replica sets maintain the same data set. When you connect to a replica set, you connect to the primary node (by default). Any changes you make to the primary node will be distributed to the secondary nodes.</p><p>The secondary nodes are ready to take over the primary node if it becomes unhealthy. This is great for a production environment where connection to our MongoDB data is critical.</p><p>Sounds amazing I know! So let’s get started.</p><h3>Summary</h3><p>In this guide, we’ll setup a replica set of three nodes. A <strong>primary</strong> and two <strong>secondary</strong> instances. You may also decide to increase the number of secondary nodes to further improve the dependability of your set.</p><h4>Ports</h4><p>We’ll be using the default port numbers, these can be changed to suit your network/firewall configuration.</p><ul><li>Primary — <strong>27017</strong></li><li>Secondary — <strong>27020</strong></li><li>Secondary — <strong>27030</strong></li></ul><h4>Prerequisites</h4><p>You’ll need either MongoDB Enterprise or Community Server running on your machine.</p><p>You can check this with mongosh . This’ll connect you to a mongod that is running on default port <strong>27017</strong>.</p><h3>Step 1</h3><p>Let’s create two directory structures for our secondary nodes.</p><p>This is considered a preference, so feel free to use folders that work for you.</p><h4>Ubuntu</h4><p>On Ubuntu, MongoDB makes the following folders for the primary node:</p><ul><li>config — /etc/mongod.conf</li><li>db — /var/lib/mongodb</li><li>log — /var/log/mongodb.log</li></ul><p>We’ll create similar folders for the secondary nodes but keep them all together for simplicity. We’ll then need to give the mongo user mongodb ownership of these folders.</p><pre>sudo mkdir -p /var/lib/mongodb-sec1/db<br>sudo mkdir -p /var/lib/mongodb-sec1/log <br>sudo mkdir -p /var/lib/mongodb-sec1/config<br><br># Give MongoDB&#39;s user, mongodb ownership of the folder<br>sudo chown -R mongodb:mongodb /var/lib/mongodb-sec1<br><br>sudo mkdir -p /var/lib/mongodb-sec2/db<br>sudo mkdir -p /var/lib/mongodb-sec2/log <br>sudo mkdir -p /var/lib/mongodb-sec2/config<br><br>sudo chown -R mongodb:mongodb /var/lib/mongodb-sec2<br><br># Repeat above if you&#39;ve would like more than two secondary nodes</pre><h4>Windows</h4><p>On Windows, MongoDB makes the following folders for the primary node:</p><ul><li>config —C:\Program Files\MongoDB\Server\*version*\data</li><li>db — C:\Program Files\MongoDB\Server\*version*\config</li><li>log — C:\Program Files\MongoDB\Server\*version*\log</li></ul><p>Let’s make the sub-folders for our secondary nodes. Please feel free to change the location of the parent folder to what suits you.</p><pre>mkdir c:\monngodb-sec1\db<br>mkdir c:\monngodb-sec1\config<br>mkdir c:\monngodb-sec1\log<br><br>mkdir c:\monngodb-sec2\db<br>mkdir c:\monngodb-sec2\config<br>mkdir c:\monngodb-sec2\log</pre><h3>Step 2</h3><p>Inside of each of the secondary node folders we created in step 1, create a mongod.cnf inside of the config folder.</p><p>In each of these files, add the following:</p><pre>--dbpath &quot;*PATH* /db&quot;<br>--logpath &quot;*PATH* /log/mongod.log&quot;<br>--storageEngine &quot;wiredTiger&quot;<br>--port *NODE PORT*</pre><p>Where <strong>*PATH*</strong> is the directory to your secondary node’s parent folder (Remember to use absolute paths!).</p><p>For example, using the folder setup I made in step 1 on Ubuntu.</p><pre>#/var/lib/mongodb-sec1/config/mongod.conf<br><br>--dbpath &quot;var/lib/mongodb-sec1/db&quot;<br>--logpath &quot;var/lib/mongodb-sec1/log/mongod.log&quot;<br>--storageEngine &quot;wiredTiger&quot;<br>--port 27020</pre><pre>#/var/lib/mongodb-sec2/config/mongod.conf<br><br>--dbpath &quot;var/lib/mongodb-sec2/db&quot;<br>--logpath &quot;var/lib/mongodb-sec2/log/mongod.log&quot;<br>--storageEngine &quot;wiredTiger&quot;<br>--port 27030</pre><h3>Step 3</h3><p>Next, we’re going to start the primary node and specify that it’s part of a replica set.</p><pre>sudo mongosh --dbpath &quot;*DBPATH*&quot; --logpath &quot;*LOGPATH*&quot; --port *PORT* --storageEngine=wiredTiger --journal --replSet *name*</pre><p>Where:</p><ul><li><strong>dbpath </strong>= Path to your primary db folder (Something like, Ubuntu: /var/lib/mongodb, Windows: C:\Program Files\MongoDB\Server\4.4\data)</li><li><strong>logpath</strong> = Path to your primary node’s log file</li><li><strong>port</strong> = Primary node port (default = 27017)</li><li><strong>name </strong>= Name of your replica set</li></ul><p>You should see an output similar to:</p><pre>{&quot;t&quot;:{&quot;$date&quot;:&quot;2024–03–13T11:16:07.245Z&quot;},&quot;s&quot;:&quot;I&quot;, &quot;c&quot;:&quot;CONTROL&quot;, &quot;id&quot;:20697, &quot;ctx&quot;:&quot;main&quot;,&quot;msg&quot;:&quot;Renamed existing log file&quot;,&quot;attr&quot;:{&quot;oldLogPath&quot;:&quot;/var/log/mongodb/mongod.log&quot;,&quot;newLogPath&quot;:&quot;/var/log/mongodb/mongod.log.2024–03–13T11–16–07&quot;}}</pre><h3>Step 4</h3><p>Now, create a new terminal session.</p><p>Let’s connect to our primary instance again in a new session and see if we can see any databases.</p><pre>&gt; mongosh --port 27017<br><br>test&gt; show dbs<br>MongoServerError[NotPrimaryOrSecondary]: node is not in primary or recovering state</pre><p>We need to create a replica set configuration and add the primary node as the first member.</p><pre>&gt; rsconfig={_id: *name*, members:[{_id:0,host:&quot;localhost:27017&quot;}]}<br><br>{<br>  _id: *name*,<br>  members: [ { _id: 0, host: &#39;localhost:27017&#39; } ]<br>}</pre><p>Where *name* is your replica set name you set earlier.</p><p>Let’s now assign the configuration</p><pre>&gt; rs.initiate(rsconfig)<br><br>{ ok: 1}</pre><p>If you run show dbs again you should now see</p><pre>&gt; show dbs<br>admin    48.00 KiB<br>config  176.00 KiB<br>local   308.00 KiB</pre><h3>Step 5</h3><p>Now we’ve correctly set up the primary node, let’s attach our secondary nodes to the set!</p><p>Let’s create another terminal session (You should have three open😱)</p><p>You’ll need to open a new terminal each time, remember to keep the old ones open! If your terminal takes you to a new line after you enter this, the node hasn’t started. Check your variables in the script.</p><p>For each of your secondary nodes:</p><pre>sudo mongod --dbpath &quot;*DBPATH*&quot; --logpath &quot;*LOGPATH*&quot; --port *PORT* --storageEngine=wiredTiger --journal --replSet *name*</pre><p>Where:</p><ul><li><strong>dbpath </strong>= Path to your secondary node’s db folder</li><li><strong>logpath</strong> = Path to your secondary node’s log file</li><li><strong>port</strong> = Secondary node port</li><li><strong>name </strong>= Name of your replica set</li></ul><p>Now, let’s head back to the primary node terminal session. (Should be the second one)</p><p>For each of your secondary nodes:</p><pre>&gt; rs.add(&quot;localhost:*PORT*&quot;)<br><br>{<br>  ok: 1,<br>  &#39;$clusterTime&#39;: {<br>    clusterTime: Timestamp({ t: 1710330078, i: 1 }),<br>    signature: {<br>      hash: Binary.createFromBase64(&#39;AAAAAAAAAAAAAAAAAAAAAAAAAAA=&#39;, 0),<br>      keyId: Long(&#39;0&#39;)<br>    }<br>  },<br>  operationTime: Timestamp({ t: 1710330078, i: 1 })<br>}</pre><p>Where <strong>*PORT*</strong> is the port of your secondary node. In our example, 27020 and 27030.</p><p>You can check if they’ve been added with</p><pre>rs.status()</pre><p>You should see your nodes inside of the members[] field! 🚀</p><h3>Step 6</h3><p>Now we’ve added the secondary nodes to the replica set, we need to inform them that they’re working for the big boss primary node.</p><p>On Ubuntu, they should already know. You can check this with:</p><pre>&gt; show dbs<br>uncaught exception: Error: listDatabses failed: {...<br># If you get this error, you&#39;ll need to tell the secondary node it works for the primary node</pre><p>Open another terminal session :)</p><p>You’ll need to perform the steps below for each of your secondary nodes</p><pre>mongosh --port *SECONDARY NODE PORT*</pre><pre>&gt; rs.secondaryOk()<br>Setting read preference from &quot;primary&quot; to &quot;primaryPreferred&quot;</pre><h3>Testing</h3><p>Head back to the primary node session.</p><pre>use *Database name*</pre><p>Next, we’ll create a database and add two entries. They should also exist on the secondary nodes which we’ll check after.</p><pre>&gt; db.employee.insert({&quot;forename&quot;: &quot;Bruce&quot;, &quot;surname&quot;: &quot;Wayne&quot;});<br><br>{<br>  acknowledged: true,<br>  insertedIds: { &#39;0&#39;: ObjectId(&#39;65f1980aa49338de9b12158e&#39;) }<br>}<br><br>&gt; db.employee.insert({&quot;forename&quot;: &quot;Clark&quot;, &quot;surname&quot;: &quot;Kent&quot;});<br><br>{<br>  acknowledged: true,<br>  insertedIds: { &#39;0&#39;: ObjectId(&#39;65f19883a49338de9b12158f&#39;) }<br>}</pre><p>Now let’s check if the database is created.</p><pre>&gt; show dbs<br><br>admin         80.00 KiB<br>config       244.00 KiB<br>*Database name*   40.00 KiB<br>local        444.00 KiB</pre><p>Great, now let’s check if it’s also on our secondary nodes.</p><p>Switch to one of your secondary node terminal sessions and run show dbs again. You should see the populated database you just created.</p><h3>Connecting</h3><p>By default, you have to connect to your primary node unless you’re using shell.</p><h4>URI</h4><p>Works for DataGrip, MongoDB, Mongoose, Motor…</p><pre>mongodb://localhost:27017/?directConnection=true&amp;appName=mongosh+2.1.0</pre><h4>Shell</h4><pre>mongosh - port 27017</pre><h3>Optional: Setting priority</h3><p>At certain events, an election will take place to determine which set member will become the primary. For example, if the server restarts or your primary node becomes unhealthy.</p><p>This can cause the primary node to change. To solve this, you can set the priority of each node. The higher the priority, the more likely they’ll win elections.</p><p>We’ll set our primary node on the default port of <strong>27017 </strong>to a higher priority than the secondary nodes. This will make it highly likely it’ll win every election whenever they happen.</p><pre># retrieve the replica set configuration and assign it to a variable<br>&gt; cfg = rs.conf()<br><br>{<br>  _id: &#39;replica&#39;,<br>  version: 5,<br>  term: 1,<br>  members: [<br>    {<br>      _id: 0,<br>      host: &#39;localhost:27017&#39;,<br>      arbiterOnly: false,<br>      buildIndexes: true,<br>      hidden: false,<br>      priority: 1,<br>      tags: {},<br>      secondaryDelaySecs: Long(&#39;0&#39;),<br>      votes: 1<br>    },<br>    {<br>      _id: 1,<br>      host: &#39;localhost:27020&#39;,<br>      arbiterOnly: false,<br>      buildIndexes: true,<br>      hidden: false,<br>      priority: 1,<br>      tags: {},<br>      secondaryDelaySecs: Long(&#39;0&#39;),<br>      votes: 1<br>    },<br>    {<br>      _id: 2,<br>      host: &#39;localhost:27030&#39;,<br>      arbiterOnly: false,<br>      buildIndexes: true,<br>      hidden: false,<br>      priority: 1,<br>      tags: {},<br>      secondaryDelaySecs: Long(&#39;0&#39;),<br>      votes: 1<br>    }<br>  ],<br>...</pre><p>Let’s set the priority of the nodes in the variable cfg</p><pre>cfg.members[0].priority = 2<br>cfg.members[1].priority = 1<br>cfg.members[2].priority = 1</pre><p>Lastly, let’s assign the new configuration.</p><p><strong>WARNING: This will cause an election and will close all client connection for 10–20 seconds.</strong></p><pre>&gt; rs.reconfig(cfg)<br><br>{<br>  ok: 1,<br>  &#39;$clusterTime&#39;: {<br>    clusterTime: Timestamp({ t: 1710335144, i: 1 }),<br>    signature: {<br>      hash: Binary.createFromBase64(&#39;AAAAAAAAAAAAAAAAAAAAAAAAAAA=&#39;, 0),<br>      keyId: Long(&#39;0&#39;)<br>    }<br>  },<br>  operationTime: Timestamp({ t: 1710335144, i: 1 })<br>}</pre><p>If there’s a server restart, or some other unexpected election. We can be confident the primary node will continue to be on port 27017.</p><h3>Summary</h3><p>We’ve succesfully setup a MongoDB Replica set with a single primary node and secondary nodes for a production environment! The primary node transmits changes in it’s database to the secondary nodes, increasing data redundency.</p><p>References:</p><ul><li>For a great windows guide by E-MultiSkills Database services: <a href="https://www.youtube.com/watch?v=91PCBRJxkh0">https://www.youtube.com/watch?v=91PCBRJxkh0</a></li><li>Adjust Priority for Replica Set Member: <a href="https://www.mongodb.com/docs/manual/tutorial/adjust-replica-set-member-priority/">https://www.mongodb.com/docs/manual/tutorial/adjust-replica-set-member-priority/</a></li><li>About replica set elections: <a href="https://www.mongodb.com/docs/manual/core/replica-set-elections/">https://www.mongodb.com/docs/manual/core/replica-set-elections/</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8c028cb02a07" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>