Full MERN Stack App: 0 to deployment on Kubernetes — part 1

In this article series, I am going to cover almost everything a fresh DevOps engineer needs to be aware about. In this first part, I will talk about setting up a React web app and preparing the app to talk to your backend.

Kavindu Chamiran
6 min readSep 12, 2019
Things we are going to talk about!

Hello everyone! Kubernetes is one of the hottest topics in the tech industry today. Kubernetes is an open-source orchestration system for Docker containers and is backed by Google. Some of its competitors are Docker Swarm and Mesos. But Kubernetes won the container orchestration war because of the set of great features it provides. Kubernetes go hand-in-hand with DevOps as it enables many practices in the DevOps world. In this series of articles, I am going to talk about,

  1. Setting up a MERN stack for development.
  2. Containerizing the app using Docker.
  3. Creating a CI/CD pipeline for the app.
  4. Deploying the app on a Kubernetes cluster.
  5. Serving the deployed app using Nginx.
  6. Setting up domain names and certificates (HTTPS).
  7. How to use storage buckets for stateful apps.
  8. Monitoring the health of the cluster.
  9. Setting up auto-scaling to handle high load.
“kubernetes” & “devops” managed to keep the trend steady for the past year!

My prime goal of this series is to teach you how to deploy your developed app adhering to DevOps practices rather than teaching you how to develop a MERN stack app. The latter can be found anywhere on the internet but a comprehensive guide on the prior is not easily found. But I will talk about the key points in the app development process. If you are looking for a tutorial on React and NodeJS, then this is not for you. But if you already have the knowledge and wish to learn how to deploy it on Kubernetes, then prepare a jug of coffee, pour a cup and bear with me through this long, long, long series of articles!

That being said, I am using a MERN stack app I created for the first part. It is called ClouDL and it can be used to download torrent files on the cloud. It is an alternative to Seedr. Why pay for Seedr when you can create your own “Seedr”? The source code is available on GitLab. It touches several aspects of Kubernetes such as,

  • Pods
  • Services
  • Deployments
  • Storage

This is just a small portion of Kubernetes but if you master these 4, you know enough to deploy your own apps on Kubernetes. The rest can be self-learned as you go. Still with me? Let’s dive in!

Setting up the MERN stack

In this section, you will learn how to,

  • Set up a NodeJS back-end and an ExpressJS server
  • Connect it to MongoDB
  • Setting up REST API endpoints.
  • Communicate with the front-end using SocketIO

MongoDB

Let’s start with MongoDB. My plan is to run a separate MongoDB pod in the cluster. So I’m not going to install MongoDB locally. Instead, let’s fire up a MongoDB docker container. First, install Docker from the official website. Then,

docker run -d -p 27017-27019:27017-27019 --name mongodb-service mongo:4.0.4

This will pull the MongoDB version 4.0.4 from the Docker hub, then start a new container (as a daemon) named mongodb, then bind the local ports 27017~27019 to the container. Now you can use MongoDB just like it was installed locally! This is the magic of Docker. Please note that the database is not persistent because I have not connected a volume to this container. But for development, that is not an issue as long as you don’t stop the container. Later on, when we deploy, I will attach a Google Cloud Storage bucket.

Folder structure

Let’s create the front-end and back-end now. We will have 3 folders inside it.

  • server: this folder will contain our ExpressJS server and SocketIO server with NodeJS doing its thing.
  • client: this folder will contain everything React!
  • worker: no need to really worry about this for now. remember I told you that my app downloads torrents? this folder contains python-written workers to handle download jobs.

Initializing front-end

I am going to initialize a React app in the client folder using create-react-app. I hope you have NodeJS already installed.

npm install -g create-react-appcreate-react-app clientcd client && npm start
create-react-app initializing a new React project

This will start a development server at http://localhost:3000. Open the link in your browser to view the app. The rest is React development, which is not covered in this series. After filling some JS files and CSS files, you will end up with something like this.

ClouDL Dashboard

My simple app has 5 views.

  • Home
  • Login
  • Register
  • Dashboard
  • Jobs

The login and register requests are carried over REST to the back-end ExpressJS server. Once logged in, it talks to the NodeJS backend using SocketIO. The python workers also talk to the NodeJS server using SocketIO. Front-end is connected to workers through the back-end.

I will talk about how I configured the SocketIO client and REST client because that will come in handy at a later time.

SocketIO

There will be more than one component using the SocketIO client and I do not want the app to initialize a new connection per every component. So what I am going to do is create a separate file “webSocket.js” and put it in my “utils” folder. Then create the web socket object there, make the connection and export the socket object. Then whenever a component needs the socket client, I am importing this object instead of creating a new SocketIO client. This pattern is called singleton and used when you want to limit the number of instances of a particular class to only one.

webSocket.js

REST

For REST requests, I am using the popular axios npm library. It does not necessarily need to be implemented using the singleton pattern because REST clients initialize connections per request basis. So you can import axios in every component needed or follow the singleton pattern, but it won’t make any difference.

authActions.js

Note that the SocketIO connection is initialized at path “/socket/” rather than the root and the REST requests are also originating from a special path “/api/”. This is done for a reason. When the app is deployed, the front-end does not know where our back-end is. In order to communicate with the back-end, we need middleware to catch the requests originating from the front-end and redirect them to where back-end lives and then deliver the responses from the back-end, back to the front-end. We are using Nginx for that. Nginx can be many things and a reverse proxy is one of them! We will see how to do that in the 3rd part of the series.

Conclusion

We initialized a new React project and configured it for SocketIO and REST connections. I know I didn’t explain how the React app became what it is now from that rotating neutron page! As I stated earlier, this is not a React tutorial. You are more than welcome to explore my Git repository. If I have time, I will write another series on React development. We will come back here when we are containerizing the app, setting up a CI/CD workflow and finally deploying the app. Until then, leave it be.

In the second part of the series, I am going to talk about the backend and how to set up the ExpressJS and SocketIO servers. There are a few things you need to be aware of if you plan to containerize your app. I will talk about them in detail. I hope this article was interesting and you will also read the second part. Just click the link below. See you then!

PS: Claps are appreciated!

--

--