In this article, I will cover how you can setup MERN stack application on Kubernetes.

Prerequisites

It is assumed that you have an understanding of the following tools/concepts and have them installed on your system:

Docker

Minikube

NodeJS

Introduction

The purpose of this article is to familiarize you with the deployment process of MERN stack on Kubernetes. We have minimal requirements on our side:

Deployment of the server (NodeJS)

Deployment of the client (ReactJS)

Initiation of services (MongoDB)

In addition to that, we will get hands-on experience to:

Inspect status of the deployments, pods, services.

Start/Stop the deployments, pods, services whenever we need to.

Inspect the logs and descriptions of individual deployments, pods, and services.

Lets Dive In Coding

We start by creating our base-directory mern-stack.

Within that directory, we will create the following files and directories:-

Client/Dockerfile

Server/Dockerfile

server-deployment.yaml

client-deployment.yaml

For simplicity, I created 2 folders for separation of concern, Client folder includes the React app as front-end, while Server folder includes the NodeJS app as back-end. As we need two different docker images for the Kubernetes deployment, Client and Server folders, each would have their own Dockerfile. Having docker images to be ready, is a precursor to the deployment of Kubernetes. In addition to that, server-deployment.yaml is used to build deployment for NodeJS app (back-end) on Kubernetes, while client-deployment.yaml is used for ReactJS app (front-end) on Kubernetes.

Now let’s start coding, paste the following lines in Client/Dockerfile to dockerize the front-end of the app.

WORKDIR /usr/src/app/client COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD ["npm", "start"]

We have our file ready to build the docker image, now move on to paste the following lines in Server/Dockerfile to dockerize the back-end.

WORKDIR /usr/src/app/server COPY package*.json ./ RUN npm install COPY . . EXPOSE 3010 CMD ["npm", "start"]

We have both front-end and back-end docker files ready. Now let’s move on to the Kubernetes setup files.

Now paste the following lines in server-deployment.yaml placed in the root directory.

kind: Deployment metadata: name: mongo spec: selector: matchLabels: app: mern-stack-app-server replicas: 1 template: metadata: labels: app: mern-stack-app-server spec: containers: - name: mongo image: mongo:latest imagePullPolicy: IfNotPresent ports: - containerPort: 27017 volumeMounts: - name: data mountPath: /data readOnly: false volumes: - name: data persistentVolumeClaim: claimName: mongo-data --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mongo-data labels: app: mern-stack-app-server spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: v1 kind: Service metadata: name: mongo labels: app: mern-stack-app-server spec: ports: - name: mongo port: 27017 targetPort: 27017 type: NodePort selector: app: mern-stack-app-server --- apiVersion: apps/v1 kind: Deployment metadata: name: mern-stack-app-server spec: selector: matchLabels: app: mern-stack-app-server replicas: 1 template: metadata: labels: app: mern-stack-app-server spec: containers: - name: mern-stack-app-server image: mern-stack-app-server:1.0.0 imagePullPolicy: Never ports: - containerPort: 3010 volumeMounts: - name: data mountPath: /data readOnly: false volumes: - name: data persistentVolumeClaim: claimName: mongo-data

Above code, will create the following:-

1 deployment of Server app

1 deployment of MongoDB

Persistent volume claim for MongoDB and attachment to server app for data persistence

MongoDB service for MongoDB database communication with server app

Now, paste the following lines of code in client-deployment.yaml in the root directory.

kind: Deployment metadata: name: mern-stack-app-client spec: selector: matchLabels: app: mern-stack-app-client replicas: 1 template: metadata: labels: app: mern-stack-app-client spec: containers: - name: mern-stack-app-client image: mern-stack-app-client:1.0.0 imagePullPolicy: Never ports: - containerPort: 3000

Above mentioned code, will create the client-side deployment. This is all the coding files we need for Kubernetes deployment. Rest is just the commands for appropriate exposure of components to each other.

In the app, replace the mongo host in mongodb connection string, by mongo, like this:

const connection = "mongodb://mongo:27017/kubernetes-app"

Guide to Build for deployment on Kubernetes

Make sure you are in the root directory of your project. Run the following commands sequentially, in order to deploy on Kubernetes:

this will start the minikube cluster single node.

minikube start

this will make docker inside minikube accessible via cmd.

eval $(minikube docker-env)

build docker server-app image.

docker build -t mern-stack-app-server:1.0.0 ./server -f ./server/Dockerfile --no-cache

build docker client-app image.

docker build -t mern-stack-app-client:1.0.0 ./client -f ./client/Dockerfile --no-cache

deploy server-app on kubernetes using kubectl.

kubectl apply -f server-deployment.yaml

deploy client-app on kubernetes using kubectl.

kubectl apply -f client-deployment.yaml

get the server-app and client-app pod name, and expose it to localhost access.

kubectl get pods kubectl port-forward <pod name here including 'mern-stack-app-server'> 32111:3010 kubectl port-forward <pod name here including 'mern-stack-app-client'> 32000:3000

This would make the server-app accessible via http://localhost:32111 and the client-app at http://localhost:32000.

Managing MERN Stack On Kubernetes

Now, as your app is up and running on Kubernetes cluster, you must know what and how to perform operations on the running app.

Inspecting Kubernetes Components

kubectl describe pods <pod_name> kubectl describe deployments <deployment_name> kubectl describe services <service_name> kubectl describe pvc <pvc_name> kubectl describe pv <pv_name>

Inspecting Logs

kubectl logs <pod_name> kubectl logs <deployment_name> kubectl logs <service_name>

In order to keep listening to logs, add -f after kubectl logs in the above commands.

Interact with the container inside Pod

kubectl exec -it <pod_name> -- /bin/bash

Stopping/Deleting Kubernetes Components

kubectl delete -f server-deployment.yaml kubectl delete -f client-deployment.yaml

In conclusion, MERN Stack app can be easily deployed and configured on Kubernetes cluster, if the right procedure and technique is followed, as mentioned in this article.