MongoDB Replica set using Docker Networking and Docker Compose

16 / Dec / 2015 by Navjot Singh 0 comments

Recently, I got a chance to dockerize a traditional MongoDB replica set. Currently, I am doing it for QA and UAT environment where MongoDB replica set is setup on a single host. So, in this blog, we will do it on a single host using Docker Networking and Docker Compose.


Scenario: Set up a MongoDB replica using version 3.0.5 set using three Docker containers from a single docker image and run the containers using Docker Networking and Docker Compose.

We will be using ubuntu base image to setup MongoDB replication as follows:

      1. Our first goal will be to create a base image in which we will have MongoDB installed. So, let’s first create a MongoDB base image from ubuntu image using below Dockerfile:
        cat Dockerfile
        FROM ubuntu:14.04
        MAINTAINER navjot.singh[at]tothenew[DOT]com
        RUN apt-key adv --keyserver hkp:// --recv 7F0CEB10
        RUN echo "deb trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list
        RUN apt-get update && apt-get install  mongodb-org=3.0.5 \
                mongodb-org-server=3.0.5 \
                mongodb-org-shell=3.0.5 \
                mongodb-org-mongos=3.0.5 \
        RUN mkdir -p /var/lib/mongodb && echo "mongodb-org hold" | sudo dpkg --set-selections && echo "mongodb-org-server hold" | sudo dpkg --set-selections && echo "mongodb-org-shell hold" | sudo dpkg --set-selections && echo "mongodb-org-mongos hold" | sudo dpkg --set-selections && echo "mongodb-org-tools hold" | sudo dpkg --set-selections
        CMD ["mongod","--dbpath=/var/lib/mongodb"]
      2. Run the below command in the directory where the above Dockerfile is present to create image:
        docker build -t mongodb-base-image .
      3. Our next step will be to create an image for MongoDB replica set such that it can be used for master as well as slaves of MongoDB replica set.
      4. We will be using Dockerfile and a script (say to complete our task. We will add in the image and will pass it into “CMD” parameter of Dockerfile so that the script gets executed whenever container comes up.
        set -x
        $MONGOD --fork --replSet fame --noprealloc --smallfiles --logpath $MONGO_LOG
        sleep 30
        $MONGO --host $SLAVE --eval db
        while [ "$?" -ne 0 ]
        echo "Waiting for slave to come up..."
        sleep 15
        $MONGO --host $SLAVE --eval db
        if [ "$ROLE" == "master" ]
        $MONGO --eval "rs.initiate()"
        checkSlaveStatus $SLAVE1
        $MONGO --eval "rs.add(\"${SLAVE1}:27017\")"
        checkSlaveStatus $SLAVE2
        $MONGO --eval "rs.add(\"${SLAVE2}:27017\")"
        tailf /dev/null
      5. When a container starts with ROLE as master, the script will start MongoDB, initiates replica set then wait and add slaves into the replica set. If the slaves are not up yet, the master will keep waiting before adding them to the replica set.This script contains all the logic. First we have set few variable in the script then have spawned MongoDB process and waited for 30 seconds to provide a buffer time to MongoDB.The script first checks the “ROLE” environment variable for “master” and execute the commands to initiate the replica set. Before proceeding further, master checks if the slaves have come up only then add the slave to the replica set.
        “ROLE”, “SLAVE1” and “SLAVE2” are passed as environment variable into the master container where the values of SLAVE1 and SLAVE2 are the hostname of slave containers.
        When the container starts with ROLE other than master, the script will start MongoDB.
      6. We then add the script using the below Dockerfile. The configuration file of MongoDB could also be added from the host if needed. Please ensure the bind address in the mongod.conf file is commented. We will use the image that we have created in step 2.
        cat Dockerfile
        FROM mongodb-base-image
        MAINTAINER navjot.singh[at]tothenew[DOT]com
        ADD mongod.conf /etc/mongod.conf
        ADD /root/
        CMD ["bash","/root/"]
      7. Run the below command to create an image from this Dockerfile.
        docker build -t mongodb-replica-set .
      8. Now, we are done creating a mongodb-replica-set image. Let’s create docker-compose.yml file to start the MongoDB replica set as below:
        cat docker-compose.yml
         image: mongodb-replica-set
         net: mongo-net
          ROLE: master
          SLAVE1: slave1
          SLAVE2: slave2
         hostname: mongodb
         container_name: mongodb
         image: mongodb-replica-set
         net: mongotnet
         hostname: slave1
         container_name: $S1
         image: mongodb-replica-set
         net: mongo-net
         hostname: slave2
         container_name: slave2
      9. We are using “mongodb-replica-set” for all three containers and are inside the same network “mongo-net” We are using hostname slave1 and slave2 for slave container and passing these hostnames as an environment variable SLAVE1 and SLAVE2 respectively in the master container. If “ROLE” is not set, the container will be started as slave container.
      10. Run the below command to start the mongodb replica set inside the directory where the docker-compose.yml is present.
        docker-compose up -d 

Now, we have successfully created MongoDB replica set on the single host. In the next blog, we will setup multiple host for setting up MongoDB replica set.


Leave a comment -