MERN Stack and Docker Containers for Web Apps
By: Ali Haidar
Tags: React, Nodejs, Software Development, Web Development, Mongodb

MERN Stack and Docker Containers for Web Apps

Outline

In this article we are going to go through the main blocks to build a full stack web application with a database. The idea is to implement a web interface using the React framework to show — add — delete on a todo list, a backend API that will act as our controller using NodeJS and Express, and finally a MongoDB database to store the todos.

We will go through those steps to build the whole project:

Project Architecture : Specify and described the main components in the application as docker containers.

: Specify and described the main components in the application as docker containers. Front-end : A one page react application to show a list of todos, append to it, and delete from it.

: A one page react application to show a list of todos, append to it, and delete from it. Back-end: An express server with a simple API to get the todos, add and delete from the list.

Architecture

Containers architecture of the 3 main components

In this application we will use docker containers to run the 3 different components separately. And we will be using docker-compose to make the connection between those containers when starting the app. In each project we will have a Dockerfile that will be used by docker-compose to start it.

Express Server

For the nodejs backend express server we will use the base image to compile and build the application and run it inside the container, we will expose the port “8000” where the server will be listening for incoming requests. The necessary commands are present in the figure below, make sure to put the file in the main project’s directory.

Docker file for express server app

React Front-end

We can do the same thing with the front-end app, because we are using react. It uses npm as its package manager, and we can build and run our project using node as well. For this app we will expose the port 3000 where the front-end can be visited on from the browser.

Docker file for front-end app

MongoDB instance

We will use the base image from docker hub for the mongoDB that will be listening on the default port “27017”. We can always connect to this instance inside a container from cmd or from any application, in our case we will make connections from the express server app as you will see in the docker-compose configuration.

Docker-Compose

Since we will have 3 components running in separate containers, we will use compose to manage those applications and control the networking between them. To achieve this, one has to write a configuration file called “docker-compose.yml” which will basically describe how the services will be called and what ports to map to, and volumes to mount inside the containers. This file must be present in the main directory of the project outside the applications directories.

We will link the node service to the mongo service and pass it as an environment variable so that the express server can connect to the mongoDB instance that is running in another container ( since it will have a different IP address — this point is important). For the “volumes” tag used in node-app and react-app, this will mount the directories where we have our files so that if we make changes while docker is running our containers, we can have live updates and hot reloads automatically without restarting the containers. The ports tags are used to map the ports from the machine to inside the containers so we can access them from outside.

Notes

To test the applications separately, we can run in each container alone without compose. To do this we have to build the images and run them from the cli. For example to do this for the react application we can first build the image like so:

docker build -t react-todo .

And then run the image we called “react-todo” using this command:

docker run -p 3000:3000 react-todo

Note that we map the port “3000” so that we can access the application from localhost.