Deploy Node.js in Kubernetes

  1. GitHub Repository Link

  2. Install Docker Desktop

  3. Create Docker Hub Account

  4. Install kubectl

  5. Install Minikube

» What are we building?

Hello, everyone! In this article, we’ll explore how to create a Kubernetes deployment and services, and then deploy our Node.js app on a Kubernetes (K8s) cluster. “K8s” it’s just an acronym for Kubernetes.

So let’s get started.

» Create Node.js App

To start off, we’ll create a simple Node.js application. If you already have a Node.js app, you can use that instead.

mkdir k8s-nodejs-app
cd k8s-nodejs-app
npm init -y

Open the project in VS code and create a file named index.js in the project dir.

If you get confuse with the project structure, look at the repository given above.

In index.js file; Paste the following code:

// index.js
var express = require('express');
var app = express();
require('dotenv').config();

app.get('/', function (req, res) {
    res.send('{ "response": "Hey There! This is Working" }');
});

app.get('/signin', function (req, res) {
    res.send('{ "response": "Hello! Please sign in with your account credentials" }');
});

app.listen(process.env.PORT || 5000);

module.exports = app;

Here we have a Express.js server with two routes (/ and /signin) that respond with JSON messages. It listens on a port defined in environment variables or defaults to 5000.

Now open the terminal and run the following command to install the needed packages.

npm install express dotenv
npm install --save-dev mocha supertest nodemon

Once done add the following script in package.json file:

"start": "nodemon index.js",

Create a .env file in root and add the following port:

```env
PORT=3000

» Create Dockerfile

Now that we have our Express.js application, let’s containerize it using Docker.

Create a Dockerfile (Dockerfile) (with no extension) and paste the following code:

FROM node:latest
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 4000
CMD [ "node", "index.js" ]

What is happening?

This is a Dockerfile that sets up a Node.js application. It:

  • Uses the latest Node.js image.
  • Sets the working directory.
  • Copies package.json and installs dependencies.
  • Copies the rest of the application.
  • Exposes port 4000.
  • Runs index.js when a container is started.

Now with this Dockerfile, we can easily create a Docker image for our Express.js application and run it in a container.

» Create Docker Image

Now we have to create a docker image and for that you need a docker hub account. So for that go to Create Docker Hub Account and complete the sign up process for an account. You will also need docker installed on your computer so for that visit this site: Install Docker Desktop and navigate to link according to your OS. And then follow the instructions given there. It’s simple to set up docker. Just follow the instructions.

After all is done open docker desktop and signin using your credentials that you used for Docker hub account.

Now create a docker image: Open your project in VS code and in terminal run:

docker build -t <username>/<image-name> .

Replace username with your docker hub username and image name with whatever you want to name your docker image.

After it’s done creating an image let’s run the command docker images to check all the images that we have and there you should have your docker file image name.

docker images

» Create Docker Container

Once we have docker image ready let’s create a container for it. So for that run the command:

docker run -d -p 3000:3000 <username>/<image-name>

And that’s it! The Docker container should be accessible on port 3000.

When you visit docker desktop you should have the conatiner.

» Check the Container and image

To check the list of container run:

docker ps   

and there you can find your container with the unique id. So make sure you save this ID somewhere because we will be needing it ahead. This will not work if your docker daemon(docker desktop app) is not open so make sure to open the docker desktop and sign in to your account.

To check the list of images run:

docker images

And there you will find the status for image and it should be running.

Now when you visit localhost:3000 you should have your express app up and running.

» Delete the Container

Now that we have made sure, that we can dockerize our app, let’s just delete the container by running the command:

docker rm -f <conatiner-id> 

» Push image to Docker Hub

Now we want to push our image to docker hub, for that run the command:

docker login 

and it might or might not ask for your credentials and just login you in if docker daemon is running.

And you should have the message login succeeded.

And to push the image to docker hub just run the command:

docker push <username>/<image-name>:latest 

Latest refers to the tag name.

Now when you visit docker hub you should have your image over there.

» Install Minikube

Now we want to create a Kubernetes Cluster.

For this you will need Minikube installed. So for that visit this website Install Minikube and install minkube according to your OS.

Then Verify your installation by using this command in terminal: 

minikube start

This command downloads the necessary files, sets up a VM or container, and starts the Kubernetes cluster.

» Install kubectl

And to use Minikube we should have kubectl (Cube Control) installed. Kubectl will allow us to interact with the Minikube Kubernetes cluster. And we can use it to create, update, delete, view k8s pods, services, and deployments.

You can visit this site Install kubectl to install kubectl and do it according to your OS.

And to check it version run the command in the terminal:

kubectl version --client

» Deployments and services

Now we will deploy our application in a Kubernetes Cluster.

For that we will be needing a Deployment file that will create Pods where our application will run and Service file that will configure a Service which will expose the application to an endpoint so that we can access the application from browser.

So head back to VS code and create 2 files named: deployment.yaml, and deploymentservice.yaml.

» Deployment File

Open the deployment.yaml file and paste the following code:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8-nodejs-app-deployment
  labels:
    app: nodeapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nodeapp
  template:
    metadata:
      labels:
        app: nodeapp
    spec:
      containers:
      - name: nodeserver
        image: username/image-name:latest
        ports:
        - containerPort: 3000
  • apiVersion: apps/v1 tells Kubernetes that we’re using the apps/v1 version of the API to create a Deployment.
  • kind: Deployment specifies that this configuration file defines a Deployment, which is a resource for managing a set of replicated Pods.

Next, we have the metadata section:

  • name: k8-nodeks-deployment is the name of our Deployment.
  • labels are key-value pairs attached to the Deployment. In this case, we’re labeling it with app: nodeapp. Labels help us organize and select resources within Kubernetes.

The spec section describes the desired state of the Deployment:

  • replicas: 1 specifies that we want one replica of our application running. You can increase this number to scale your application.
  • selector defines how Kubernetes will identify the Pods managed by this Deployment. It matches Pods with the label app: nodeapp.

The template section defines the structure of the Pods that will be created by this Deployment:

  • metadata within template includes labels for the Pods. Here, we’re labeling the Pods with app: nodeapp.
  • spec within template describes the container that will run inside each Pod.

Under the containers array, we define the specific container for our application:

  • name: nodeserver is the name of the container.
  • image: username/image-name:latest specifies the Docker image for the container. In this case, it’s pulling the latest version of the username/node-app image from Docker Hub.
  • ports defines the ports that the container will expose. Here, containerPort: 3000 means that the container will listen on port 3000.

This setup allows Kubernetes to manage our Node.js application, ensuring it runs consistently and can be scaled easily.

» Deployment Service File

Now we will work on Kubernetes Service configuration file. This file will define a Service that will expose our Node.js application to the outside world.

Paste the following code in deploymentservice.yaml file:

apiVersion: v1
kind: Service
metadata:
  name: nodeapp-service
spec:
  selector:
    app: nodeapp
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 3000
    nodePort: 31110
  • apiVersion: v1 indicates that we’re using the v1 version of the API.
  • kind: Service specifies that this configuration file defines a Service, which is a way to expose an application running on a set of Pods as a network service.

The metadata section:

  • name: nodeapp-service is the name of our Service. This name is used to reference the Service within the Kubernetes cluster.

The spec section describes the desired state of the Service:

  • selector: specifies how the Service will find the Pods it targets. It matches Pods with the label app: nodeapp. This means that any Pod with the label app: nodeapp will be included in this Service.

The type of Service:

  • type: LoadBalancer tells Kubernetes to create an external load balancer for this Service. This allows the Service to be accessible from outside the Kubernetes cluster. It’s especially useful in cloud environments where Kubernetes can provision a load balancer from the cloud provider.

Finally, we define the ports for the Service:

  • protocol: TCP specifies that the Service will use the TCP protocol.
  • port: 5000 is the port on which the Service will be exposed. External traffic will be directed to this port.
  • targetPort: 3000 is the port on the Pods that the Service will forward traffic to. In our case, the container in the Pod is listening on port 3000.
  • nodePort: 31110 is an optional field that specifies the port on each node where this service can be accessed. If omitted, Kubernetes will assign a random port in the range 30000-32767.

This enables external access to our Node.js application running in a Kubernetes cluster, making it accessible on port 5000 through a load balancer.

» Creating the Deployment and Service

Now we have to create deployment and service in cluster using the configuration files that we just created.

So now to create a deployment from deployment.yaml file, we have to run this command:

kubectl apply -f deployment.yaml

We will do same for the service file, run:

kubectl apply -f deploymentservice.yaml

» Check Pods and Services

Now we want to confirm if the pods and service are running is to get the list of running pods, we have a command:

kubectl get service

And you should get your service name in the list.

And to check the list of pods run:

kubectl get pods

And there you have the list of pods running.

Now the status that you see there should be showing running. But for you it can be possible that the status is not running, because pods might take time to run, so after few seconds try running the get pods command and when the status of your pod is running only then move ahead.

At last if you want to access the application on browser run the command:

minikube service nodeapp-service

This should automatically take you to the browser. And there you can see the response form index.js file. Also check if signin page works and it should.


And that’s all for this blog. I hope you enjoyed it and found it useful. Also if you have any doubts please drop a message on our discord server. The link can be found below.

👉 And I’ll see you in next one, till then bye-bye and take care.