MongoDB Replica set using Docker Networking and Docker Compose
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:
- 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] - Run the below command in the directory where the above Dockerfile is present to create image:
[js]docker build -t mongodb-base-image .[/js]
- 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.
- 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 30checkSlaveStatus(){
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] - 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. - 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] - Run the below command to create an image from this Dockerfile.
[js]docker build -t mongodb-replica-set .
[/js] - 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] - 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.
- 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.
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.
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