Setting up MongoDB

Other posts in this series:  Docker for developers

In this article you will learn about setting up MongoDB and some nuances about persisting data using volumes.

Let's dive into the Docker goodness

Step 1: Download the seed project

Open a terminal and type git clone https://github.com/attosol/nginx-and-nodejs-on-docker.git.

Step 2: Change your directory and checkout the first commit

$ cd nginx-and-nodejs-on-docker
$ git checkout a9caad2cc

Review the docker-compose.yml file. It will look as follows:

version: '2'

services:
  database:
    image: ${DATABASE_VERSION}
    networks:
      - backend
    container_name: ${DATABASE_CONTAINER_NAME}
    volumes:
      - mongo-data:/data/db
      - ./docker/scripts:/scripts
      - ./docker/data:/data

networks:
  backend:
    driver: bridge

volumes:
  mongo-data:

Step 3: Docker magic in action

Run docker-compose up -d

Creating network "nodenginxseed_backend" with driver "bridge"
Creating volume "nodenginxseed_mongo-data" with default driver
Creating mongodb ... 
Creating mongodb ... done

That one little command did a bunch of things for you! To use MongoDB now run the following:

$ docker exec -it mongodb bash
root@568df5929409:/# 

# There is a file called "/data/sample.json", that you can use to seed your database with data. 
# There is a script too! Let's allow execution of script and execute it.
root@568df5929409:/# chmod 755 ./scripts/mongoseed.sh 
root@568df5929409:/# ./scripts/mongoseed.sh 

REMOVING Sample Database
==========================
MongoDB shell version v3.4.8
connecting to: mongodb://127.0.0.1:27017/sample
MongoDB server version: 3.4.8
{ "ok" : 1 }

Importing Documents in a new Database called Sample
===================================================
2017-09-08T09:42:50.910+0000	connected to: localhost
2017-09-08T09:42:50.931+0000	imported 100 documents

DONE!

# Fetch data if you like :)
root@568df5929409:/# mongo sample
> db.users.find({"name":"Mitchell Herrera"}).pretty()

You can see, how easy it was to install MongoDB and initialise it with data, that too WITHOUT installing anything on your OS (except Docker)? Now, let's see what's going on in a little more detail.

Explanation of the Docker goodness

.env file

The .env file that you see at the root of the project, contains all the variables that you reference to in the docker-compose.yml.

# Project Information
COMPOSE_PROJECT_NAME=node-nginx-seed
TAG=1.0

# Database Information
DATABASE_VERSION=mongo:3.4.8
DATABASE_CONTAINER_NAME=mongodb

docker-compose.yml file

The docker-compose.yml file is also created at the root of the project where you will be running docker-compose commands from. It contains instructions about building your environment. Consider this an effort in the right direction since it will help you save plenty of time during development.

It is a YML (rhymes with camel) file, and starts with version attribute (set to 2 or higher). The service attribute lets you tell Docker about the containers you would like to spin and has a 1:1 relationship with the containers. Thus, every service will spin up a unique container. If you have a docker-compose.yml file like the following, you will be able to create a network and spin a database container by executing an extremely simple docker-compose up command:

version: '2'

services:
  database:
    image: ${DATABASE_VERSION}
    networks:
      - backend
    container_name: ${DATABASE_CONTAINER_NAME}
    volumes:
      - mongo-data:/data/db
      - ./docker/scripts:/scripts
      - ./docker/data:/data

networks:
  backend:
    driver: bridge

volumes:
  mongo-data:
  • database - One of the service that implies role of the container.
  • image - Tells Docker which image to pull from dockerhub. DATABASE_VERSION is a variable declared in the .env file as you have seen above.
  • networks - Uses a defined bridge network called backend.
  • container_name - This is a friendly container name. In this example it is mongodb
  • volumes - This is the secret sauce due to which the data is persisted. Notice that there are three mappings:
  • mongo-data which is mapped to /data/db. This is the place where mongo creates its database by default.
  • ./docker/scripts is mapped to /scripts. Basically, it is telling Docker that, "hey... when I say /scripts, I mean... ./docker/scripts on my local box".
  • In a similar way, /data is mounted as ./docker/data inside of the container.

/scripts/mongoseed.sh file

This is a regular shell script that is currently available in the /scripts folder. To execute this script, you have to get inside of the container as you have already seen in the section above: Docker magic in action. Basically, you run docker in interactive mode and supply the friendly name like:

$ docker exec -it mongodb bash

Once you are in, you can run any command as you would. The mongoseed.sh file looks as follows:

#!/bin/bash

if [ -e /scripts/.seeddata ]
then
  printf "\nWARNING"
  printf "\n==========\n"
  printf "Data already seeded!\n"
  printf "If you want to remove and reseed, run 'rm /scripts/.seeddata'\n\n"
else
	printf "\nREMOVING Sample Database\n==========================\n"
	mongo sample --eval "db.dropDatabase()"
	printf "\nImporting Documents in a new Database called Sample\n"
	printf "===================================================\n"
	mongoimport --db sample --collection users --file /data/sample.json --jsonArray
  touch /scripts/.seeddata
  printf "\nDONE!\n"
fi

Type exit to get out of the container.

NOTE: The sample.json file is created using this fabulous tool http://www.json-generator.com/.*

You can now run the following to discard all your changes and switch back to master branch.

$ git clean -f
$ git checkout master

What next?

Well, stay tuned for upcoming articles. You may contact us at contact@attosol.com for your software and consultancy requirements.

© 2023, Attosol Private Ltd. All Rights Reserved.