Build and Deploy MERN Stack Applications with Kubernetes

In recent years, the MERN stack has gained a lot of popularity among developers due to its efficiency and scalability. MERN stands for MongoDB, Express, React, and Node.js, and is a full-stack web development technology. Combining the MERN stack with Kubernetes provides a flexible, secure, and scalable environment to run your applications.

In this blog post, we will guide you through the process of deploying a MERN stack application on Kubernetes. We will use Docker to build our images and Kubernetes to deploy and manage our containers.

Prerequisites

Prerequisites:

To follow this tutorial, you should have some basic knowledge of Docker and Kubernetes. You should also have the following installed on your system:

Introduction

The purpose of this article is to familiarize you with the deployment process of MERN stack on Kubernetes. 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.

Step 1: Create a MERN stack application

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

We will start by creating a simple MERN stack application. For this tutorial, we will create a basic application that allows users to add and delete notes. You can use any application you like, but for simplicity, we will use the following repository: https://github.com/adrianhajdin/project_mern_memories.

After cloning the repository, navigate to the project's directory and install the dependencies:

cd project_mern_memories
npm install

Next, start the application:

npm start

Open your browser and go to http://localhost:3000. You should see the application running.

Step 2: Dockerize the MERN stack application

The next step is to dockerize the MERN stack application. To do this, we need to create a Dockerfile. Create a new file in the root directory of your project and name it Dockerfile. Add the following code:

# Use an official Node.js runtime as a parent image
FROM node:14.15.4-alpine

# Set the working directory to /app
WORKDIR /app

# Copy the package.json and package-lock.json to /app
COPY package*.json ./

# Install app dependencies
RUN npm install

# Copy the application code to /app
COPY . .

# Expose the port that the application is listening on
EXPOSE 3000

# Start the application
CMD ["npm", "start"]

The Dockerfile is fairly simple. It starts with an official Node.js runtime, sets the working directory to /app, and copies the package.json and package-lock.json files to /app. It then installs the dependencies and copies the application code to /app. Finally, it exposes the port that the application is listening on and starts the application.

Next, we need to build the Docker image. Open a terminal and navigate to the project's directory. Run the following command to build the Docker image:

docker build -t mern-stack .

This will build the Docker image with the tag mern-stack. The dot at the end of the command indicates that the Dockerfile is in the current directory.

Once the image is built, you can run it with the following command:

docker run -p 3000:3000 mern-stack

Step 3: Deploy the MERN stack application on Kubernetes

With a Docker image in hand, we can now deploy the MERN stack application on Kubernetes. To do this, we'll create a Kubernetes deployment and a service.

Create a new file in the project's directory called deployment.yml, and add the following code:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mern-stack
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mern-stack
  template:
    metadata:
      labels:
        app: mern-stack
    spec:
      containers:
        - name: mern-stack
          image: mern-stack:latest
          ports:
            - containerPort: 3000

The deployment specifies a replica set of 3 and a selector that matches the app label of the pod template. The pod template is specified with a container that is labeled with the app label and points to the Docker image we built earlier. It also exposes port 3000, which is the port our application is running on.

Next, create a new file in the project's directory called service.yml, and add the following code:

apiVersion: v1
kind: Service
metadata:
  name: mern-stack
spec:
  selector:
    app: mern-stack
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer

The service specifies a selector that matches the app label of the deployment, and it exposes port 80, which is the port that we want to access our application on. The targetPort of 3000 points to the containerPort we specified in the deployment's pod template. Finally, we specify the type of service as LoadBalancer.

Once you have the deployment and service files in place, you can deploy them to your Kubernetes cluster using the kubectl command line tool. In a terminal, navigate to the project's directory and run the following command:

kubectl apply -f deployment.yml
kubectl apply -f service.yml

This will create the deployment and service in your Kubernetes cluster.

To access your application, you'll need to obtain the IP address of the LoadBalancer service. In a terminal, run the following command:

kubectl get services

Step 4: 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.

Scaling Deployment

kubectl scale --replicas=4 deployment/mern-stack

Inspecting Logs

kubectl logs <pod_name>
kubectl logs deployment/mern-stack
kubectl logs <service_name>

You can also use the kubectl logs command with the -f flag to stream the logs in real-time

This will stream the logs to your terminal in real-time. You can use the Ctrl+C key combination to stop streaming the logs.

Note that if you have multiple replicas of your deployment running, you'll need to specify the name of the pod whose logs you want to retrieve. You can use the kubectl get pods command to list all the pods running in your deployment.

Interact with the container inside Pod

To interact with a container inside a pod, you can use the kubectl exec command. This command allows you to run a command inside a container in a running pod.

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

Once you're inside the container, you can run any command that is available in the container's filesystem. For example, you can run ls to list the files in the container, or npm install to install a package.

Once you're done interacting with the container, you can exit the shell by typing exit. This will return you to the terminal on your local machine.

Stopping/Deleting Kubernetes Components

To delete the deployment and service, run the following commands in your terminal:

kubectl delete deployment mern-stack
kubectl delete service mern-stack

Conclusion

In this tutorial, we've covered how to deploy a MERN stack application on Kubernetes. We started by dockerizing the application, creating Docker images for the client and server, and then deploying them on Kubernetes. We then covered some basic management tasks, including scaling the application, performing rolling updates, and monitoring the application using the Kubernetes Dashboard. With Kubernetes, you can create a flexible, secure, and scalable environment for running your MERN stack applications.