SoFunction
Updated on 2025-03-10

Docker builds the implementation of mongodb single-node replica set

background

In development, it is easy for us to start a normal mongodb database service through docker. But sometimes in order to keep it consistent with the online environment, or to take advantage of certain features of the mongodb replica set, we need to deploy the mongodb replica set locally. Replica sets often require starting multiple mongodb services as replica set members, while the notebook resources usually used for development are relatively limited. In view of this, the official documentation provides a solution, which can directly convert a single node mongodb service into a single node replica set (standlone replica set)(/docs/manual/tutorial/convert-standalone-to-replica-set/)

Startup steps

According to the official documentation, if you use docker to deploy the service, then there are the following steps:

  • The first step is, if there is already a running ordinary mongodb container service. At this time, the service needs to be closed and the service needs to be closed andSpecify--replSetparameterRestart the service or restart a new mongodb container.

    If the service name and container name of mongodb aremongodb_rs, the run port map is27017:27017, the copy set name isrs0, the data storage directory is specified as/srv/mongodb/db0, the data volume mount directory is./data:/srv/mongodb/db0. So The file can be written as follows:

    version: "3"
    services:  
      mongodb_rs:
        network_mode: bridge
        container_name: mongodb_rs
        image: mongo:latest
        ports:
          - "27017:27017"
        restart: always
        # environment:
        #   MONGO_INITDB_ROOT_USERNAME: username
        #   MONGO_INITDB_ROOT_PASSWORD: pwd
        command: mongod --port 27017 --replSet rs0 --dbpath /srv/mongodb/db0
        volumes:
          - ./data:/srv/mongodb/db0
  • The second step is to start the mongodb service by executing the following command.

    docker-compose up -d mongodb_rs
  • Step 3: Enter the container mongosh and execute the initial replica set command

    docker exec -it mongodb_rs mongo
    # mongosh
    ()
    
    # ---
    # > ()
    # {
    #	 "info2" : "no configuration specified. Using a default configuration for the set",
    #	 "me" : "f76081e20602:27017",
    #	 "ok" : 1
    # }
    # rs0:SECONDARY>
    # rs0:PRIMARY>|
  • Step 4: Exit the container and the container service is running normally

Probable problems

After following the above steps, the container service can usually run normally and the application can connect normally. Here it is basically successful. Test with golang code:

package main

import (
	"context"
	"fmt"
	"log"

	"/mongo-driver/bson"
	"/mongo-driver/mongo"
	"/mongo-driver/mongo/options"
)

func main() {
	clientOpts := ().ApplyURI("mongodb://localhost:27017/?replicaSet=rs0")
	client, err := ((), clientOpts)
	if err != nil {
		(err)
	}
	colls, _ := ("admin").ListCollectionNames((), {})
	("colls: %v\n", colls)
}
// colls: [ ]

However, sometimes local program code may not be able to connect to the replica set service, and the console will report a problem similar to a connection error. The reason for the error is thatThe replica set does not recognize the member host

Under a single node replica set, the machine is both a master and a slave, in the containermongo shellcan be viewed inmembersThere is only one member,namefor"f76081e20602:27017", So if you encounter unreachable connection or other similar errors, the root cause is that the replica set started locally cannot be recognizedf76081e20602thishost

()
---
rs0:PRIMARY> ()
{
	"set" : "rs0",
	"date" : ISODate("2022-05-06T18:59:21.417Z"),
# ...	
	"members" : [
		{
			"_id" : 0,
			"name" : "f76081e20602:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 1433,
			"optime" : {
				"ts" : Timestamp(1651863555, 1),
				"t" : NumberLong(1)
			},
		# ...
		}
	],
# ...
}

Solution

I have encountered the above problem. There are many articles on Baidu CSSDN with the same content. They all say that in this case, the application needs to be started through a container, and the application and the mongdb replica set service are placed in the same docker network, so that it can be connected normally. This is indeed possible, but it seems to be too troublesome and feels like going on a wrong path.

It is already known from the above content that is a member of the replica sethostThe recognition problem is, so when initializing the mongodb replica set, we can explicitly specify the membershost, does not use the default replica set configuration. Specifically, change the third step in the startup step to:

  • Entermongosh

    docker exec -it mongodb_rs mongo
  • Custom configuration

    # mongosh
    conf = {
       _id : "rs0",
       members: [
          { _id: 0, host: "<Native IP Address>:27017" },
       ]
    }
  • Initialize the replica set

    # mongosh
    (conf)

In this way, by specifying member IP, Mongo single-node replica set can accurately identify replica set members. This method also applies to multi-node replica sets if there is a connection problem.

This is the end of this article about the implementation of docker building a single node replica set. For more related content of docker building a single node replica set, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!