MongoDB Replica set using Docker Networking and Docker Compose

16 / Dec / 2015 by Navjot Singh 2 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.

1-HWfG5YkyX5atHZjDFrHfaw

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:

        [js]cat Dockerfile
        FROM ubuntu:14.04
        MAINTAINER navjot.singh[at]tothenew[DOT]com
        RUN apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv 7F0CEB10
        RUN echo "deb http://repo.mongodb.org/apt/ubuntu 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 \
        mongodb-org-tools=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"]
        [/js]

      2. Run the below command in the directory where the above Dockerfile is present to create image:

        [js]docker build -t mongodb-base-image .[/js]

      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 startUp.sh) to complete our task. We will add startUp.sh in the image and will pass it into “CMD” parameter of Dockerfile so that the script gets executed whenever container comes up.

        [js]cat startUp.sh[/js]

        [js]#!/bin/bash
        set -x
        MONGO_LOG="/var/log/mongodb/mongod.log"
        MONGO="/usr/bin/mongo"
        MONGOD="/usr/bin/mongod"
        $MONGOD –fork –replSet fame –noprealloc –smallfiles –logpath $MONGO_LOG
        sleep 30

        checkSlaveStatus(){
        SLAVE=$1
        $MONGO –host $SLAVE –eval db
        while [ "$?" -ne 0 ]
        do
        echo "Waiting for slave to come up…"
        sleep 15
        $MONGO –host $SLAVE –eval db
        done
        }

        if [ "$ROLE" == "master" ]
        then
        $MONGO –eval "rs.initiate()"
        checkSlaveStatus $SLAVE1
        $MONGO –eval "rs.add(\"${SLAVE1}:27017\")"
        checkSlaveStatus $SLAVE2
        $MONGO –eval "rs.add(\"${SLAVE2}:27017\")"
        fi
        tailf /dev/null
        [/js]

      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 startUp.sh 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.

        [js]cat Dockerfile[/js]

        [js]FROM mongodb-base-image
        MAINTAINER navjot.singh[at]tothenew[DOT]com
        ADD mongod.conf /etc/mongod.conf
        ADD startUp.sh /root/startUp.sh
        CMD ["bash","/root/startUp.sh"]
        [/js]

      7. Run the below command to create an image from this Dockerfile.

        [js]docker build -t mongodb-replica-set .
        [/js]

      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:

        [js]cat docker-compose.yml[/js]

        [js]mongodb-master:
        image: mongodb-replica-set
        net: mongo-net
        environment:
        ROLE: master
        SLAVE1: slave1
        SLAVE2: slave2
        hostname: mongodb
        container_name: mongodb
        mongodb-slave1:
        image: mongodb-replica-set
        net: mongotnet
        hostname: slave1
        container_name: $S1
        mongodb-slave2:
        image: mongodb-replica-set
        net: mongo-net
        hostname: slave2
        container_name: slave2[/js]

      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.

        [js]docker-compose up -d [/js]

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.

FOUND THIS USEFUL? SHARE IT

comments (2)

  1. ATrivedi

    Thank for this blog.

    I am following your given steps but i am facing some problem.
    1- When I run (docker build -t mongodb-replica-set .)
    below issue:
    ADD mongod.conf /etc/mongod.conf
    lstat mongod.conf: no such file or directory

    2-When I run (docker-compose up -d)
    below issue:
    WARNING: The S1 variable is not set. Defaulting to a blank string.
    Creating slave2
    Creating mongodb
    Creating dcompose_mongodb-slave1_1

    ERROR: for mongodb-slave1 Cannot create container for service mongodb-slave1: network mongotnet not found

    ERROR: for mongodb-slave2 Cannot create container for service mongodb-slave2: network mongo-net not found

    ERROR: for mongodb-master Cannot create container for service mongodb-master: network mongo-net not found
    ERROR: Encountered errors while bringing up the project.

    My environment -Ubuntu 16.04, Mongodb 3.2.11

    what should i do for above issues?

    Kindly suggest me for the same.

    Reply
    1. Sajin Varghese

      You need to create a network first using “docker network create” command, also there is an error in line 14 of compose file. U need to define a valid name for docker container

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *