Creating a FARM Stack Dev Environment with Docker Compose — Part 1 of 3: MongoDB
Introduction
This year I started developing applications utilizing the FastAPI Python framework paired with a React front-end and a MongoDB database (FARM). Previously for development I had mainly used the Flask Python framework with a front-end using JavaScript libraries such as JQuery and Handlebars or Jinja templating with a MySQL database. If I wasn’t using a framework for the back-end like Flask or FastAPI, I was helping a company develop their own framework.
I like FastAPI because it has an easy-to-use documentation framework built in. The documentation also doubles as a way I can test the API.
As for using MongoDB as a database, I find it easy to work with using Python, since the BSON documents resemble dict type objects. Also, having used relational databases such as Microsoft SQL Server and MySQL most of my career, reducing the need for normalization by adding the needed data to a single document is growing on me. Especially given that storage is so much more cost effective than when I started my career. I am also finding that the MongoDB aggregation pipelines are good enough for basic reporting needs.
As for React on the front-end, I must use it for some of the application integrations I am building. For example, Shopify applications use Next.js with React for applications.
I do a lot of development on my laptop with Ubuntu Linux installed on it. So rather than installing each of these technologies on my laptop, I create the application stacks using Docker Compose. If I move my work to my Windows Surface laptop I can use the same docker-compose.yml and corresponding files to get up and running quickly.
In this series, I will share my experience building a FARM stack with Docker Compose. The first part of this series will focus on the MongoDB part of the stack. And the following parts of the series will build upon each other.
What You Will Need
Docker Compose
You need to install Docker Compose on your system. For installing Docker Compose on your system please reference https://docs.docker.com/compose/install/
Text Editor
You will need to run your favorite text editor to modify the files and scripts used in this series. Any text editor will do. On my Linux system I use gedit or VIM. No judgment. Use whatever is easier.
GitHub Repository
You can cut and paste the code from this demonstration. You can also download the code used in this tutorial straight from my GitHub repository. The repository can be cloned from https://github.com/chupati/farm-part-1.
Running the MongoDB Part of the Stack
Once you download the repository from https://github.com/chupati/farm-part-1 you can type the following command in your terminal or command prompt. You must be in the same directory as the file “docker-compose.yml”
docker-compose up
You can get up and running without reading this series any further with the command above. To access the database through your browser go to http://localhost:8081
I will discuss the components of the GitHub repository below so you can have reference as to what each part of the MongoDB part of the stack accomplishes.
The Docker Compose Configuration File
The file “docker-compose.yml” are the instructions used for running the stack. In this part we will focus on the MongoDB part of the “docker-compose.yml” file. The source code for the “docker-compose.yml” file can be found at https://github.com/chupati/farm-part-1/blob/main/docker-compose.yml. You can also cut and paste the contents from the section below.
Source Code of docker-compose.yml
version: '2'
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: OTNmYTdjYmZkMjE5ZmYzODg0MDZiYWJh
volumes:
- ./data/mongo:/data/db
- ./data/mongo-init:/docker-entrypoint-initdb.d
ports:
- "27017:27017"
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: OTNmYTdjYmZkMjE5ZmYzODg0MDZiYWJh
Version
The version of the Docker Compose configuration I chose to use for this stack is 2. That is signified by the first line of the file. You can find documentation on that specific version at https://docs.docker.com/compose/compose-file/compose-file-v2/.
Version Configuration:
version: '2'
Services
This is where we will place the configuration for the MongoDB part of the stack. We will have two services running for MongoDB. The services are called “mongo” and “mongo-express”. The service “mongo” is the actual MongoDB part of the stack. The service “mongo-express” is for the convenient web user interface that can be used to connect to the MongoDB server. If you are familiar with MongoDB you can use your preferred MongoDB client.
Image
The image part of each service will make sure we use the “mongo” and “mongo-express” images from the public Docker hub repository. The mongo image can be found at https://hub.docker.com/_/mongo and the mongo-express image can be found at https://hub.docker.com/_/mongo-express.
Mongo Service Image Configuration:
image: mongo
Mongo-Express Service Image Configuration:install
image: mongo-express
Restart
The “restart” option will be set to “always” for the “mongo” and “mongo-express” services. This will make sure the services restart upon failures.
restart: always
Environment
We use environment variables to hold the values of the database username and passwords. You can get a list of the environment variables at the “mongo” and “mongo-express” Docker hub image URLs listed above.
Mongo Service Environment Configuration:
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: OTNmYTdjYmZkMjE5ZmYzODg0MDZiYWJh
Mongo-Express Service Environment Configuration:
Initial Installationenvironment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: OTNmYTdjYmZkMjE5ZmYzODg0MDZiYWJh
Ports
This environment will make sure the MongoDB port 27017 and Mongo-Express port 8081 are both exposed and ready to use on the host machine.
Mongo Service Port Configuration:
ports:
- "27017:27017"
Mongo-Express Service Port Configuration:
ports:
- 8081:8081
Volumes
To make sure the MongoDB data is persistent we map the directory on the host where the MongoDB data will be stored. In our case we will use “data/mongo” of the repository. If you do not map a volume to store the data, then the “mongo” service container will start fresh with no data every time it is restarted.
We will also map an install directory to the directory “/docker-entrypoint-initdb.d” in the “mongo” service. This directory contains an install script that runs “mongoimport” to install initial data in a compressed data file containing JSON entries on each line. We will go into the initial install in a bit.
Mongo Service Volumes Configuration:
volumes:
- ./data/mongo:/data/db
- ./data/mongo-init:/docker-entrypoint-initdb.d
Initial Installation
Installing is the same as running the service. You simply type the following at your terminal or command prompt.
docker-compose up
If there is no “data/mongo” directory detected then the script file data/mongo-init/install.sh will be run. The install script can be found at https://github.com/chupati/farm-part-1/blob/main/data/mongo-init/install.sh.
Source Code for data/mongo-init/install.sh:
echo IMPORTING COLLECTION
tar -xzvf /docker-entrypoint-initdb.d/issues.tar.gz — directory /tmp
mongoimport — authenticationDatabase=admin --username=$MONGO_INITDB_ROOT_USERNAME --password=$MONGO_INITDB_ROOT_PASSWORD --db=farmdemo --collection=issues --file=/tmp/issues.json
echo “CLEANING UP”
rm /tmp/issues.json
echo DONE IMPORTING
The file “data/mongo-init/issuse.tar.gz” will be unzipped and imported using the “mongoimport” command found in the install script above. The “mongoimport” command will direct the data to the “farmdata” database and “issues” collection.
When you run the script you should see a line similar to the one below when you look through the docker-compose command output. There is a lot of data in the Docker Compose output so it may be easy to miss.
2021–07–29T16:58:02.897+0000 54663 document(s) imported successfully. 0 document(s) failed to import.
Data Description
To have initial data to work with, I created an import file with selected comic publisher issues published from 2015 through 2021. The data was downloaded from “Great Comic Book” database at https://www.comics.org/.
The data file is located at “data/mongo-init/issues.tar.gz”. Importing the data creates a database called “farmdemo” and the collection “issues” in that database.
Results
After the Docker containers are all running you can access the MongoDB service user interface at http://localhost:8081.
Once the page loads you will see the “farmdemo” database. If you click on the database you will see that the “issues” collection has already been loaded for you. We will use the “issues” collection in the next part of this series when we discuss the “FastAPI” part of the Docker Compose FARM stack we are building. Part two of this series will be coming soon and will focus on the FastAPI part of the FARM stack.
MongoDB Mongo-Express Web Interface:
Mongo-Express Web Interface farmdemo Database Page:
Mongo-Express Web Interface issues Collections Page: