<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Selim</title>
    <description>The latest articles on DEV Community by Selim (@user_10d6776b9ce140).</description>
    <link>https://dev.to/user_10d6776b9ce140</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3424034%2F75c2e873-62f1-4e9c-85bd-0dc6a3740c40.jpg</url>
      <title>DEV Community: Selim</title>
      <link>https://dev.to/user_10d6776b9ce140</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/user_10d6776b9ce140"/>
    <language>en</language>
    <item>
      <title>MongoDB Replica Set Compose OS independent</title>
      <dc:creator>Selim</dc:creator>
      <pubDate>Tue, 12 Aug 2025 08:58:07 +0000</pubDate>
      <link>https://dev.to/user_10d6776b9ce140/mongodb-replica-set-compose-os-independent-1p8h</link>
      <guid>https://dev.to/user_10d6776b9ce140/mongodb-replica-set-compose-os-independent-1p8h</guid>
      <description>&lt;h2&gt;
  
  
  Quick start on how to &lt;strong&gt;containerize MongoDB Replica Set&lt;/strong&gt; on your machine.
&lt;/h2&gt;

&lt;p&gt;In about &lt;strong&gt;5 minutes&lt;/strong&gt;, the &lt;strong&gt;3-Node Replica Set&lt;/strong&gt; will be running on your machine without any prior experience with container platforms or databases.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is the purpose of a Replica Set on a single machine?
&lt;/h3&gt;

&lt;p&gt;Initializing a Replica Set on a single machine is necessary to enable certain MongoDB features such as &lt;strong&gt;Changestreams&lt;/strong&gt; for real-time applications and &lt;strong&gt;Transactions&lt;/strong&gt; for &lt;strong&gt;ACID-compliant&lt;/strong&gt; database operations.&lt;/p&gt;




&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Editor of your choice, I will be using &lt;strong&gt;Visual Studio Code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Container platform with &lt;strong&gt;Compose support&lt;/strong&gt;, I will demonstrate using both &lt;strong&gt;Docker&lt;/strong&gt; and &lt;strong&gt;Podman&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your directory should look something like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project
├── compose.yml
└── .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Copy and paste the &lt;strong&gt;compose.yml&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_1&lt;/span&gt;
    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_1&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c "&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Starting without auth for initial setup...'&lt;/span&gt;
        &lt;span class="s"&gt;if [ ! -f /shared/setup_completed ]; then&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Running without auth for replica set initialization'&lt;/span&gt;
          &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --port 27017 &amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;while [ ! -f /shared/setup_completed ]; do&lt;/span&gt;
            &lt;span class="s"&gt;sleep 1&lt;/span&gt;
          &lt;span class="s"&gt;done&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Setup completed, restarting with auth...'&lt;/span&gt;
          &lt;span class="s"&gt;pkill mongod&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Starting with auth...'&lt;/span&gt;
        &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --port 27017 --keyFile /shared/mongodb-keyfile --auth&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_1_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_1_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_keyfile:/shared&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_network&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27017:27017"&lt;/span&gt;

  &lt;span class="na"&gt;mongo_2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_2&lt;/span&gt;
    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_2&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c "&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Starting without auth for initial setup...'&lt;/span&gt;
        &lt;span class="s"&gt;if [ ! -f /shared/setup_completed ]; then&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Running without auth for replica set initialization'&lt;/span&gt;
          &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --port 27018 &amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;while [ ! -f /shared/setup_completed ]; do&lt;/span&gt;
            &lt;span class="s"&gt;sleep 1&lt;/span&gt;
          &lt;span class="s"&gt;done&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Setup completed, restarting with auth...'&lt;/span&gt;
          &lt;span class="s"&gt;pkill mongod&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Starting with auth...'&lt;/span&gt;
        &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --port 27018 --keyFile /shared/mongodb-keyfile --auth&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_2_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_2_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_keyfile:/shared&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_network&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27018:27018"&lt;/span&gt;

  &lt;span class="na"&gt;mongo_3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_3&lt;/span&gt;
    &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_3&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c "&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Starting without auth for initial setup...'&lt;/span&gt;
        &lt;span class="s"&gt;if [ ! -f /shared/setup_completed ]; then&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Running without auth for replica set initialization'&lt;/span&gt;
          &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --port 27019 &amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;while [ ! -f /shared/setup_completed ]; do&lt;/span&gt;
            &lt;span class="s"&gt;sleep 1&lt;/span&gt;
          &lt;span class="s"&gt;done&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Setup completed, restarting with auth...'&lt;/span&gt;
          &lt;span class="s"&gt;pkill mongod&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Starting with auth...'&lt;/span&gt;
        &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --port 27019 --keyFile /shared/mongodb-keyfile --auth&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_3_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_3_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_keyfile:/shared&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_network&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27019:27019"&lt;/span&gt;

  &lt;span class="na"&gt;mongo_setup&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_setup&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c "&lt;/span&gt;
        &lt;span class="s"&gt;if [ -f /shared/setup_completed ]; then&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Cluster setup already completed, skipping'&lt;/span&gt;
          &lt;span class="s"&gt;exit 0&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Generating keyfile...' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;if [ ! -f /shared/mongodb-keyfile ]; then&lt;/span&gt;
          &lt;span class="s"&gt;openssl rand -base64 756 &amp;gt; /shared/mongodb-keyfile &amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;chmod 600 /shared/mongodb-keyfile &amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;chown 999:999 /shared/mongodb-keyfile &amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Keyfile generated successfully'&lt;/span&gt;
        &lt;span class="s"&gt;else&lt;/span&gt;
          &lt;span class="s"&gt;echo 'Keyfile already exists, skipping generation'&lt;/span&gt;
        &lt;span class="s"&gt;fi &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Waiting for node startup...' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;sleep 5 &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Initializing replica set...' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;mongosh --host mongo_1 --port 27017 --eval '&lt;/span&gt;
          &lt;span class="s"&gt;try {&lt;/span&gt;
            &lt;span class="s"&gt;rs.initiate({&lt;/span&gt;
              &lt;span class="s"&gt;_id: "rs0",&lt;/span&gt;
              &lt;span class="s"&gt;members: [&lt;/span&gt;
                &lt;span class="s"&gt;{_id: 0, host: "mongo_1:27017", priority: 1},&lt;/span&gt;
                &lt;span class="s"&gt;{_id: 1, host: "mongo_2:27018", priority: 0.5},&lt;/span&gt;
                &lt;span class="s"&gt;{_id: 2, host: "mongo_3:27019", priority: 0.5}&lt;/span&gt;
              &lt;span class="s"&gt;]&lt;/span&gt;
            &lt;span class="s"&gt;});&lt;/span&gt;
            &lt;span class="s"&gt;print("Replica set initialized successfully");&lt;/span&gt;
          &lt;span class="s"&gt;} catch (e) {&lt;/span&gt;
            &lt;span class="s"&gt;print("Replica set initialization failed or already exists: " + e);&lt;/span&gt;
          &lt;span class="s"&gt;}&lt;/span&gt;
        &lt;span class="s"&gt;' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Waiting for primary election...' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;sleep 20 &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Creating admin user...' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;mongosh --host mongo_1 --port 27017 --eval '&lt;/span&gt;
          &lt;span class="s"&gt;try {&lt;/span&gt;
            &lt;span class="s"&gt;db = db.getSiblingDB("admin");&lt;/span&gt;
            &lt;span class="s"&gt;db.createUser({&lt;/span&gt;
              &lt;span class="s"&gt;user: "'$$MONGO_INITDB_ROOT_USERNAME'",&lt;/span&gt;
              &lt;span class="s"&gt;pwd: "'$$MONGO_INITDB_ROOT_PASSWORD'",&lt;/span&gt;
              &lt;span class="s"&gt;roles: [{role: "root", db: "admin"}]&lt;/span&gt;
            &lt;span class="s"&gt;});&lt;/span&gt;
            &lt;span class="s"&gt;print("Admin user created successfully");&lt;/span&gt;
          &lt;span class="s"&gt;} catch (e) {&lt;/span&gt;
            &lt;span class="s"&gt;print("User creation failed: " + e);&lt;/span&gt;
            &lt;span class="s"&gt;throw e;&lt;/span&gt;
          &lt;span class="s"&gt;}&lt;/span&gt;
        &lt;span class="s"&gt;' &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;touch /shared/setup_completed &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;echo 'Cluster setup completed successfully!'&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_setup_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_setup_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_keyfile:/shared&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_network&lt;/span&gt;

  &lt;span class="na"&gt;mongo_express&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_express&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo-express:latest&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_INITDB_ROOT_USERNAME}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_INITDB_ROOT_PASSWORD}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_MONGODB_URL=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo_1:27017,mongo_2:27018,mongo_3:27019/?replicaSet=rs0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_BASICAUTH_USERNAME=${MONGO_INITDB_ROOT_USERNAME}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_BASICAUTH_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo_network&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8081:8081"&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_1_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_2_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_3_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_setup_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_1_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_2_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_3_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_setup_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_keyfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo_network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set your admin username and password in &lt;code&gt;.env&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MONGO_INITDB_ROOT_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"root"&lt;/span&gt;
&lt;span class="nv"&gt;MONGO_INITDB_ROOT_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"pass"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Run the Compose setup in your project directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Podman:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;podman compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Wait about &lt;strong&gt;45 seconds&lt;/strong&gt;, then run the setup logs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker logs mongo_setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Podman:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;podman logs mongo_setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If everything went right the output should look like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generating keyfile...
Keyfile generated successfully
Waiting for node startup...
Initializing replica set...
Replica set initialized successfully
Waiting for primary election...
Creating admin user...
Admin user created successfully
Cluster setup completed successfully!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The final step is to map hosts &lt;strong&gt;127.0.0.1&lt;/strong&gt; to &lt;strong&gt;mongo_1, mongo_2 and mongo_3&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Windows Powershell:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start-Process powershell.exe -Verb RunAs -ArgumentList '-NoProfile', '-Command', 'Add-Content -Path "C:\Windows\System32\drivers\etc\hosts" -Value "`n127.0.0.1   mongo_1 mongo_2 mongo_3"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mac/Linux Zsh/Bash:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "127.0.0.1   mongo_1 mongo_2 mongo_3" | sudo tee -a /etc/hosts &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Access your MongoDB Replica Set
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open your browser on &lt;code&gt;http://localhost:8081/&lt;/code&gt; and login with your &lt;code&gt;.env&lt;/code&gt; credentials&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To connect via MongoDB Compass or drivers, use this connection string to enable Replica Set connectivity with automatic failover. (Be sure to replace &lt;code&gt;"root"&lt;/code&gt; and &lt;code&gt;"pass"&lt;/code&gt; with your &lt;code&gt;.env&lt;/code&gt; credentials):&lt;br&gt;
&lt;code&gt;mongodb://root:pass@127.0.0.1:27017,127.0.0.1:27018,127.0.0.1:27019/?replicaSet=rs0&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mongodb</category>
      <category>container</category>
      <category>docker</category>
      <category>database</category>
    </item>
    <item>
      <title>Local MongoDB Replica Set Cluster for Real-Time Container Apps (with Mongo Express)</title>
      <dc:creator>Selim</dc:creator>
      <pubDate>Sat, 09 Aug 2025 18:49:23 +0000</pubDate>
      <link>https://dev.to/user_10d6776b9ce140/local-mongodb-replica-set-cluster-for-real-time-container-apps-with-mongo-express-16bi</link>
      <guid>https://dev.to/user_10d6776b9ce140/local-mongodb-replica-set-cluster-for-real-time-container-apps-with-mongo-express-16bi</guid>
      <description>&lt;h2&gt;
  
  
  Run a full 3-node MongoDB replica set locally for real-time containerized applications, with authentication, failover, and Mongo Express — all in one compose.yml.
&lt;/h2&gt;

&lt;p&gt;If you’re developing &lt;strong&gt;containerized applications&lt;/strong&gt; that need &lt;strong&gt;real-time MongoDB features&lt;/strong&gt; like &lt;strong&gt;Change Streams&lt;/strong&gt;, you’ll want a local replica set.&lt;br&gt;&lt;br&gt;
This guide shows you how to run a &lt;strong&gt;3-node MongoDB cluster&lt;/strong&gt; with authentication, automatic failover, and a built-in web interface — all in &lt;strong&gt;one compose.yml file&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I built this setup &lt;strong&gt;primarily for Podman&lt;/strong&gt;, but it works with &lt;strong&gt;most container platforms&lt;/strong&gt;, including Docker, with no changes.&lt;/p&gt;

&lt;p&gt;You’ll get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;3-node MongoDB replica set&lt;/strong&gt; — perfect for local development &amp;amp; real-time features&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keyfile-based authentication&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Automatic &lt;strong&gt;replica set initialization&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A configurable &lt;strong&gt;root admin user&lt;/strong&gt; via &lt;code&gt;.env&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mongo Express&lt;/strong&gt; for browser-based DB management&lt;/li&gt;
&lt;li&gt;Ready-to-use connection strings for primary and secondary nodes&lt;/li&gt;
&lt;li&gt;Works with &lt;strong&gt;Docker &amp;amp; Podman&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Why Use a Replica Set Locally?
&lt;/h2&gt;

&lt;p&gt;Running a MongoDB replica set locally lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test &lt;strong&gt;high availability&lt;/strong&gt; scenarios — simulate node failures&lt;/li&gt;
&lt;li&gt;Work with &lt;strong&gt;real-time features&lt;/strong&gt; like Change Streams&lt;/li&gt;
&lt;li&gt;Develop apps that &lt;strong&gt;mirror production environments&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;read preference&lt;/strong&gt; configurations with primary and secondary nodes&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;The cluster is defined in a single &lt;code&gt;compose.yml&lt;/code&gt; that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;keyfile-generator&lt;/strong&gt; – creates a secure keyfile for internal node authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mongo1, mongo2, mongo3&lt;/strong&gt; – the three replica set members&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mongo-express&lt;/strong&gt; – a web-based MongoDB admin interface&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  1 &lt;code&gt;.env&lt;/code&gt; File
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in the same directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change these values to your preferred admin credentials.&lt;/p&gt;




&lt;h3&gt;
  
  
  2 &lt;code&gt;compose.yml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Here’s the full configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;keyfile-generator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;alpine:latest&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;no"&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;sh -c "&lt;/span&gt;
        &lt;span class="s"&gt;apk add --no-cache openssl &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;if [ ! -f /data/keyfile ]; then&lt;/span&gt;
          &lt;span class="s"&gt;openssl rand -base64 756 &amp;gt; /data/keyfile &amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="s"&gt;chmod 400 /data/keyfile;&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile_data:/data&lt;/span&gt;

  &lt;span class="na"&gt;mongo1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo1&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile-generator&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;27017:27017&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongoCluster&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo1_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo1_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile_data:/etc/mongo-keyfile&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c '&lt;/span&gt;
        &lt;span class="s"&gt;echo "Starting MongoDB setup..."&lt;/span&gt;
        &lt;span class="s"&gt;while [ ! -f /etc/mongo-keyfile/keyfile ]; do&lt;/span&gt;
          &lt;span class="s"&gt;echo "Waiting for keyfile..."&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
        &lt;span class="s"&gt;done&lt;/span&gt;
        &lt;span class="s"&gt;chmod 400 /etc/mongo-keyfile/keyfile&lt;/span&gt;
        &lt;span class="s"&gt;mongod --replSet rs0 --bind_ip_all --keyFile /etc/mongo-keyfile/keyfile --fork --logpath /var/log/mongod.log&lt;/span&gt;
        &lt;span class="s"&gt;for i in {1..30}; do&lt;/span&gt;
          &lt;span class="s"&gt;if mongosh --quiet --eval "db.runCommand({ping: 1})" &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;/span&gt;
            &lt;span class="s"&gt;break&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
        &lt;span class="s"&gt;done&lt;/span&gt;
        &lt;span class="s"&gt;if ! mongosh --quiet --eval "rs.status()" &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;/span&gt;
          &lt;span class="s"&gt;mongosh --eval "&lt;/span&gt;
            &lt;span class="s"&gt;rs.initiate({&lt;/span&gt;
              &lt;span class="s"&gt;_id: \"rs0\",&lt;/span&gt;
              &lt;span class="s"&gt;members: [&lt;/span&gt;
                &lt;span class="s"&gt;{ _id: 0, host: \"mongo1:27017\", priority: 2 },&lt;/span&gt;
                &lt;span class="s"&gt;{ _id: 1, host: \"mongo2:27017\", priority: 1 },&lt;/span&gt;
                &lt;span class="s"&gt;{ _id: 2, host: \"mongo3:27017\", priority: 1 }&lt;/span&gt;
              &lt;span class="s"&gt;]&lt;/span&gt;
            &lt;span class="s"&gt;})&lt;/span&gt;
          &lt;span class="s"&gt;"&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
        &lt;span class="s"&gt;for i in {1..60}; do&lt;/span&gt;
          &lt;span class="s"&gt;if mongosh --quiet --eval "db.hello().isWritablePrimary" 2&amp;gt;/dev/null | grep -q true; then&lt;/span&gt;
            &lt;span class="s"&gt;mongosh admin --quiet --eval "db.createUser({user:\"${MONGO_INITDB_ROOT_USERNAME}\",pwd:\"${MONGO_INITDB_ROOT_PASSWORD}\",roles:[{role:\"root\",db:\"admin\"}]})"&lt;/span&gt;
            &lt;span class="s"&gt;break&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
          &lt;span class="s"&gt;sleep 2&lt;/span&gt;
        &lt;span class="s"&gt;done&lt;/span&gt;
        &lt;span class="s"&gt;mongod --shutdown&lt;/span&gt;
        &lt;span class="s"&gt;sleep 3&lt;/span&gt;
        &lt;span class="s"&gt;exec mongod --replSet rs0 --bind_ip_all --auth --keyFile /etc/mongo-keyfile/keyfile&lt;/span&gt;
      &lt;span class="s"&gt;'&lt;/span&gt;

  &lt;span class="na"&gt;mongo2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo2&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile-generator&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;27018:27017&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongoCluster&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo2_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo2_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile_data:/etc/mongo-keyfile&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c "&lt;/span&gt;
        &lt;span class="s"&gt;chmod 400 /etc/mongo-keyfile/keyfile &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;exec mongod --replSet rs0 --bind_ip_all --auth --keyFile /etc/mongo-keyfile/keyfile&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;

  &lt;span class="na"&gt;mongo3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo3&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile-generator&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;27019:27017&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongoCluster&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo3_data:/data/db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo3_config:/data/configdb&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;keyfile_data:/etc/mongo-keyfile&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;bash -c "&lt;/span&gt;
        &lt;span class="s"&gt;chmod 400 /etc/mongo-keyfile/keyfile &amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="s"&gt;exec mongod --replSet rs0 --bind_ip_all --auth --keyFile /etc/mongo-keyfile/keyfile&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;

  &lt;span class="na"&gt;mongo-express&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo-express:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo-express&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo3&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8081:8081&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongoCluster&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_INITDB_ROOT_USERNAME}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_INITDB_ROOT_PASSWORD}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_MONGODB_URL=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_BASICAUTH_USERNAME=${MONGO_INITDB_ROOT_USERNAME}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ME_CONFIG_BASICAUTH_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongoCluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo1_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo1_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo2_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo2_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo3_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mongo3_config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;keyfile_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3 Starting the Cluster
&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;Podman&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;podman compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;strong&gt;Docker&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On first run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A secure &lt;strong&gt;keyfile&lt;/strong&gt; is generated&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;replica set&lt;/strong&gt; (&lt;code&gt;rs0&lt;/code&gt;) is initialized&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;root admin user&lt;/strong&gt; is created&lt;/li&gt;
&lt;li&gt;MongoDB restarts in &lt;strong&gt;auth mode&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;After the first Bootup is completed you may delete the &lt;strong&gt;keyfile-generator Container&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Connecting to the Cluster
&lt;/h2&gt;

&lt;h3&gt;
  
  
  e.g. MongoDB Compass
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Direct node connections:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primary:
&lt;code&gt;mongodb://root:pass@localhost:27017/?authSource=admin&amp;amp;directConnection=true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Secondary 1:
&lt;code&gt;mongodb://root:pass@localhost:27018/?authSource=admin&amp;amp;directConnection=true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Secondary 2:
&lt;code&gt;mongodb://root:pass@localhost:27019/?authSource=admin&amp;amp;directConnection=true&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;(Replace &lt;code&gt;root&lt;/code&gt; / &lt;code&gt;pass&lt;/code&gt; if changed in &lt;code&gt;.env&lt;/code&gt;)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Mongo Express UI
&lt;/h2&gt;

&lt;p&gt;Access &lt;strong&gt;Mongo Express&lt;/strong&gt; at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8081
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Login with your &lt;code&gt;.env&lt;/code&gt; credentials.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;TLS/SSL&lt;/strong&gt; for encrypted connections&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;Failover Logic&lt;/strong&gt; between direct node connection strings in your app&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;Change Streams&lt;/strong&gt; in your app&lt;/li&gt;
&lt;li&gt;Simulate node failures to test high availability&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mongodb</category>
      <category>containers</category>
      <category>podman</category>
      <category>realtime</category>
    </item>
  </channel>
</rss>
