Testcontainers-java: Is there a way to run a MongoDB replica set by 'GenericContainer'?

Created on 11 Apr 2019  路  7Comments  路  Source: testcontainers/testcontainers-java

It's easy to convert a standalone mongod to a replica set for testing and development:
https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set/

As for CI , I want to use TestContainers to get a MongoDB replica set, is there a better way to make this ? I have tried to use docker compose module, but it's fairly complex.

typquestion

Most helpful comment

Okay, we could be happy to close this question now:

mongo1.execInContainer("/bin/bash", "-c", "mongo --eval 'printjson(rs.initiate({_id:\"rs0\"," +
                "members:[{_id:0,host:\"M1:27017\"},{_id:1,host:\"M2:27017\"},{_id:2,host:\"M3:27017\"}]}))' --quiet");
mongo1.execInContainer("/bin/bash", "-c",
            "until mongo --eval \"printjson(rs.isMaster())\" | grep ismaster | grep true > /dev/null 2>&1;do sleep 1;done");

All 7 comments

Hi @JieHan17,

We have support for networks. Just create one and connect your containers to it. You will find some examples of usage here:
https://github.com/testcontainers/testcontainers-java/blob/master/core/src/test/java/org/testcontainers/containers/NetworkTest.java

Note that inside the network, you don't need to get mapped ports. You should use aliases (with withNetworkAliases) and configure your "cluster" as: node1:12345, node2:12345, node3:12345 where 12345 is the communication port

Hi @JieHan17,

We have support for networks. Just create one and connect your containers to it. You will find some examples of usage here:
https://github.com/testcontainers/testcontainers-java/blob/master/core/src/test/java/org/testcontainers/containers/NetworkTest.java

Note that inside the network, you don't need to get mapped ports. You should use aliases (with withNetworkAliases) and configure your "cluster" as: node1:12345, node2:12345, node3:12345 where 12345 is the communication port

Hi @bsideup ,
Thank you so much for quick reply, as I am a newbie for TestContainers, according to your comment I wrote codes below:

   @ClassRule
    public static Network network = newNetwork();

    @ClassRule
    public static GenericContainer mongo1 = new GenericContainer("mongo:4.0.8")
            .withNetwork(network)
            .withNetworkAliases("M1")
            .withExposedPorts(MONGO_PORT)
            .withCommand("--replSet rs0 --bind_ip localhost,M1");

    @ClassRule
    public static GenericContainer mongo2 = new GenericContainer("mongo:4.0.8")
            .withNetwork(network)
            .withNetworkAliases("M2")
            .withExposedPorts(MONGO_PORT)
            .withCommand("--replSet rs0 --bind_ip localhost,M2");

    @ClassRule
    public static GenericContainer mongo3 = new GenericContainer("mongo:4.0.8")
            .withNetwork(network)
            .withNetworkAliases("M3")
            .withExposedPorts(MONGO_PORT)
            .withCommand("--replSet rs0 --bind_ip localhost,M3");

And next how could do this configuration in the 'mongo' shell (using 'execInContainer') :

rs.initiate( {
   _id : "rs0",
   members: [
      { _id: 0, host: "M1:27017" },
      { _id: 1, host: "M2:27017" },
      { _id: 2, host: "M3:27017" }
   ]
})

Okay, we could be happy to close this question now:

mongo1.execInContainer("/bin/bash", "-c", "mongo --eval 'printjson(rs.initiate({_id:\"rs0\"," +
                "members:[{_id:0,host:\"M1:27017\"},{_id:1,host:\"M2:27017\"},{_id:2,host:\"M3:27017\"}]}))' --quiet");
mongo1.execInContainer("/bin/bash", "-c",
            "until mongo --eval \"printjson(rs.isMaster())\" | grep ismaster | grep true > /dev/null 2>&1;do sleep 1;done");

Hi @JieHan17,
I created a test repeating the above mentioned code of yours. I only managed to make it work, which is proven by this Travis build, using url without specifying replicaSet, for example mongodb://localhost:32769/test (in a so to speak Standalone way). Could you, please, tell me whether you managed to make this test green? Also, please, share a url string that you used.

Hi @JieHan17,
I created a test repeating the above mentioned code of yours. I only managed to make it work, which is proven by this Travis build, using url without specifying replicaSet, for example mongodb://localhost:32769/test (in a so to speak Standalone way). Could you, please, tell me whether you managed to make this test green? Also, please, share a url string that you used.

HI @silaev ,
This really blocked me a bit, but finally I managed to make it work, see:
MongoContainer,
this may be not strict enough as I always consider 'm1' as master since 'm1' is started by first.

Hi @JieHan17,
Many thanks for sharing your code. As I expected, you used endpointURI = "mongodb://" + m1.getContainerIpAddress() + ":" + m1.getFirstMappedPort(); without specifying replicaSet in a so to speak Standalone way.

From my perspective, it鈥檚 a good approach if one doesn't need any fault tolerance because MongoDB nodes do not communicate with one another when it comes to a standalone connection. Therefore, from my understanding, a single node replica set is enough in this case.

FYI: PR MongoDB module

Was this page helpful?
0 / 5 - 0 ratings