WittCode💻

Docker and MongoDB

By

Learn how to set up MongoDB using Docker. We will also go over creation scripts, security, data persistence, and more.

Table of Contents 📖

Why Docker and MongoDB?

A benefit of dockerizing Mongo is that it avoids the headache of installing and configuring database servers. Docker containers are available that are specifically designed to support Mongo, allowing us to skip all the installation. Also, using a docker container for Mongo provides a consistent and isolated environment that can be distributed and ran in different environments.

Creating the Docker Image

To begin, lets create a Dockerfile to build a Mongo image. For this demonstration, we will use Mongo version 7.0.7 as the base image.

FROM mongo:7.0.7

Now lets create an initial Mongo database. We can do this by setting the environment variable MONGO_INITDB_DATABASE.

ENV MONGO_INITDB_DATABASE=mydb

If we don't supply a value to this environment variable, then Mongo will create a database called test by default. Of course, Mongo works by creating a database the first time it is used, but creating the database here makes it so creation scripts are ran against this database as opposed to the default test database.

Database Initialization with Creation Scripts

Creation scripts are .sh or .js files placed inside the folder docker-entrypoint-initdb.d in the image. They are used for database initialization such as authentication, collection creation, data insertion, etc.

COPY init.js /docker-entrypoint-initdb.d/

Here, we are placing an initialization script called init.js inside this folder. Lets create this creation script and make it insert an entity into a collection called subscriber.

db.createCollection('subscriber');
db.subscriber.insertOne(
  {email: 'a@a.com', subscribedAt: new Date()},
);

The db object here is the Mongo database object used inside the MongoDB shell. We will see that in action in a bit.

Security

The default Mongo configuration is not secure as there is no authentication required for access. We can set a root username and password using two environment variables.

ENV MONGO_INITDB_ROOT_USERNAME=wittcode
ENV MONGO_INITDB_ROOT_PASSWORD=MySecurePassword

These environment variables create a new user and set their password. Specifically, the user is given the superuser root role and is added to the admin authentication database. To create a user with less privileges, we can use creation scripts.

Building the Image

Now all we need to do is build the image using this Dockerfile. We can build a Docker image using the docker build command.

docker build -t mongo-i:1.0.0 .

This creates an image called mongo-i with the tag version of 1.0.0.

docker images
REPOSITORY       TAG       IMAGE ID       CREATED         SIZE
mongo-i          1.0.0     40dcfa0567a9   5 seconds ago   700MB

Creating a Container

Now lets create a container from this image using the docker run command.

docker run --name mongo-c -p 27017:27017 mongo-i:1.0.0

This command will create a docker container with the name mongo-c that maps port 27017 on our local machine to port 27017 in the container. However, before we run this command, lets create a docker volume to ensure the data is persisted when the container is destroyed.

Data Persistence

To persist the data stored inside a Mongo image, we need to use docker volumes. Specifically, we need to create a volume pointing to the /data/db directory inside the image.

docker run --name mongo-c -p 27017:27017 --volume mongo-v:/data/db mongo-i:1.0.0

Now when we create different containers from this image our data will be persisted if we apply the mongo-v volume we created. Run the command to get the container up and running.

Querying MongoDB

Now lets test our configurations by accessing the container. First, run mongosh against the container with docker exec.

docker exec -it mongo-c mongosh

The command mongosh stands for MongoDB Shell. It is a JavaScript/Node environment for interacting with MongoDB. Now lets switch to our admin database.

use admin

Next, lets authenticate ourselves using the username and password we provided. We can do this with db.auth.

db.auth('wittcode', 'MySecurePassword')

Here, the first argument is the username and the second argument is the password. These are the environment variables that we set in our Dockerfile. Now lets switch back to the database we created and retrieve the inserted entity from our subscriber collection.

use mydb
db.subscriber.find()
[
  {
    _id: ObjectId("6602dfa2da4ace7499b0bc08"),
    email: 'a@a.com',
    subscribedAt: ISODate("2024-03-26T14:45:54.409Z")
  }
]
Docker and MongoDB