This article will teach you how to deploy a Node.js application to Kubernetes using Helm and Helm charts. Node.js is an open-source Javascript runtime for building server-side applications.
Kubernetes is an open-source platform that automates the deployment and management of containerized applications. Kubernetes orchestrates containerized applications and deploys them into a Kubernetes cluster.
A Kubernetes cluster contains a set of worker and master nodes. The nodes have resources for running the deployed containerized applications.
In this article, we will create a Node.js application and run it locally. We will then containerize the application using Docker. Finally, we will deploy the Dockerized Node.js application to Kubernetes using Helm and Helm charts.
Prerequisites
For you to implement the concepts in this Helm article in the easiest way:
- You must have some experience with Docker
- Understand the working of Kubernetes and creating Kubernetes YAML files.
- Know how to run kubectl commands on a Kuberenetes cluster. Kubectl helps in the deployment and management of applications. It also allows developers to communicate and interact with the Kubernetes cluster.
You also need to set up the following tools:
- Node.js: Javascript runtime: For building the Express Server.
- Docker: For containerizing the Node.js application. You must know how to create and work with Docker containers. If you are new to Docker, you can read this article.
- Vs Code: For code editing.
Note: I will show you how to install the other necessary tools. These three are the most important for you to have to get started faster.
What is Helm?
Helm is a package manager for Kubernetes applications. It packages a collection of Kubernetes YAML files and distributes them in a public and private registry. Helm bundles Kubernetes YAML files into a package known as a Helm Chart. Kubernetes YAML files are also known as Kubernetes manifest files for creating Kubernetes objects such as Kubernetes Deployment, Kubernetes Service, Configmaps, and Secrets.
These files are for deploying any containerized application to Kubernetes. We use Helm Charts as a blueprint for deploying any Kubernetes application.
You will modify some of the configurations in the YAML files in the Helm Chart. You can also create your custom Helm Chart.
We will install Helm and generate a custom Helm Chart for our Node.js application. We will then modify the YAML files in the Helm before deploying the Node.js application to Kubernetes. To understand more about Helm, read this article on Sweetcode.
I will show you how to install Helm later. Let’s first create and containerize a basic Node.js application with an Express get route.
Creating a Basic Node.js Application
We will create an Express server with a get route using Node.js. If you are new to Node.js, you can read this article to gain a better understanding. Let’s now create a basic Node.js application.
To start, create a new folder named `node-js-app`, and open it with VS Code. Next, initialize the Node.js application using the following command:
npm init-y
The working environment for our application is ready. Let’s install the dependencies for this application:
npm install express
We will use `express` to create an Express server route. In the `node-js-app` folder, create an `index.js` file. Open the file and add the following code:
const express = require('express') const cors = require('cors') const app = express() app.use(cors()) app.get('/', (req, res) => { res.json([ { "id": "1", "title": "This is my First Blog Title" }, { "id": "2", "title": "This is my Second Blog Title" }, { "id": "3", "title": "This is my Third Blog Title" }, { "id": "4", "title": "This is my Fourth Blog Title" }, { "id": "5", "title": "This is my Fifth Blog Title" } ]) }) app.listen(4000, () => { console.log('Server running on port 4000') })
The code will create a get route that displays the five blog titles. To run the Express server, use this command:
node index.js
The command will start the Express server on port `4000` as shown below:
You can then type http://localhost:4000 on your browser to view the running Express server:
Our Node.js application is running locally, let’s now containerize the application using Docker.
Containerizing the Application using Docker
We will start by building a Docker image for the Node.js application. To build a Docker image, we will need a `Dockerfile`. A `Dockerfile` contains commands (list of instructions) for building the Docker image. Let’s create our `Dockerfile` that the Docker Daemon will use:
Creating the Dockerfile
In the `node-js-app` folder, create a `Dockerfile` and add the following commands:
# It will pull node:18-alpine as the base image from Docker Hub FROM node:18-alpine # It creates the container working directory named `node` WORKDIR /node # It copies all the dependencies and libraries to the working directory COPY package.json . #It installs all the dependencies and libraries to the container RUN npm install #It copies all the source code and configuration files to the container working directory COPY . . #it exposes and runs the container to port 4000 EXPOSE 4000 #It is the command to start and run the container for the Node.js application CMD ["node", "index.js"]
Building the Docker Image
To build the Docker image using the Dockerfile above, run this Docker command in your terminal:
docker build -t <Docker Hub username>/node-app .
Remember to use your Docker Hub username when naming the Docker Image. The command will build a Docker image as shown below:
Pushing the Image to Docker Hub
To push the Docker image to Docker Hub, apply the following Docker commands sequentially:
docker login docker push <Docker Hub username>/node-app
After successfully pushing the Docker image to Docker Hub, let’s run the Docker image.
Running the Docker Image
When you run a Docker image, it automatically starts and runs a Docker container. To run this image, apply the following Docker command:
docker run -p 4000:4000 <Docker Hub username>/node-app
The command will start and run the Docker container on port 4000. You can type http://localhost:4000 on your browser to view the application running a Docker container:
We have containerized the Node.js application. Let’s now install Helm.
Installing Helm
We will install Helm on a Kubernetes cluster. In this guide, we will install Helm on a local Kubernetes cluster engine known as Minikube. Minikube allows developers to create and run the Kubernetes cluster on their local computer/machine. You can read this article on Sweetcode to gain a better understanding of Minikube.
Minikube does not require any installation since it comes with Docker Desktop. Before we install Helm, let’s start Minikube. You will apply the following `minikube` command in your terminal:
minikube start --driver=docker
The output below shows Minikube is running and using Kubectl:
Now that Minikube is running, let’s install Helm:
1. Install Helm on macOS
To install Helm on macOS, use this `brew` command from the Homebrew package manager:
brew install helm
2. Install Helm on Linux
To install Helm on Linux, run this `apt` command to :
sudo apt-get install helm
3. Install Helm on Windows
To install Helm on Windows, use this `choco` command from the Chocolatey package manager:
choco install kubernetes-helm
In this guide, I have installed Helm using `choco` as shown below:
To see some of the Helm commands, run this command in your terminal:
helm
It outputs the following Helm commands:
To check the Helm version, run this Helm command:
helm --version
The version output:
Creating a Helm a Chart
We will create a Helm chart `node-app-chart` for the Node.js application. The Helm chart will contain the default YAML files. We will modify the files before deploying our application. To create the Helm chart, run this Helm command:
helm create node-app-chart
Helm Chart Structure
To get the structure of the created Helm chart, run this command:
ls node-app-chart
The structure for the `node-app-chart` is shown below:
You can also open the `node-app-chart` folder in VS Code as shown below:
From the image above, the `node-app-chart` contains the Charts folder, Template folder, Chart.yaml file, and the Values.yaml file.
1. Charts folder
This folder contains any other dependencies for the `node-app-chart`.
2. Template folder
This folder contains all Kubernetes YAML or manifest files for creating Kubernetes objects such as Kubernetes Deployment, Kubernetes Service, Configmaps, and Secrets. In this guide, we will only require the `deployment.yaml` and `service.yaml`. We will modify these two files and add our configurations for deploying the Node.js application.
3. Chart.yaml
This YAML file contains descriptive information about the Helm chart such as the chart name and version.
4. Values.yaml
This YAML file contains the application configuration values that the other YAML files in the template folder will use. These values include the image name, container name, port mapping, number of pods, and the type of Kubernetes service.
In this guide, the `deployment.yaml` and `service.yaml` files will read and use the values in this file during the deployment.
Let’s start by modifying the Values.yaml file.
Modifying the Values.yaml File
Open the Values.yaml file and modify it using the following YAML code:
replicaCount: 2 image: repository: <Docker Hub username>/node-app pullPolicy: IfNotPresent tag: "latest" service: type: LoadBalancer port: 4000 targetPort: 4000 protocol: TCP name: node-app-service resources: {} limits: cpu: 100m memory: 256Mi requests: cpu: 100m memory: 256Mi autoscaling: enabled: false minReplicas: 1 maxReplicas: 100 targetCPUUtilizationPercentage: 80
Let’s modify the `deployment.yaml` and `service.yaml` files.
Modifying the deployment.yaml File
Open the deployment.yaml file and modify it using the following YAML code:
apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "node-app-chart.fullname" . }} labels: {{- include "node-app-chart.labels" . | nindent 4 }} spec: {{- if not.Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: {{- include "node-app-chart.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "node-app-chart.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default.Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 4000 protocol: TCP resources: {{- toYaml .Values.resources | nindent 12 }}
Modifying the service.yaml File
Open the service.yaml file and modify it using the following YAML code:
apiVersion: v1 kind: Service metadata: name: {{ include "node-app-chart.fullname" . }} labels: {{- include "node-app-chart.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: {{ .Values.service.targetPort }} protocol: {{ .Values.service.protocol }} name: {{ .Values.service.name }} selector: {{- include "node-app-chart.selectorLabels" . | nindent 4 }}
All the files we need for this guide are ready. Let’s now deploy the Node.js application to Kubernetes this Helm Chart.
Deploying the Node.js Application
To deploy the Node.js application to Kubernetes this Helm Chart, run this `Helm` command:
helm install node-app-chart
When you run the Helm command above, the following happens:
- Helm will automatically go through all of the files.
- It will then read the application configuration values and pass them to the two files: `deployment.yaml` and `service.yaml`.
- The final `deployment.yaml` and `service.yaml` files will have the correct configuration value for the Node.js application.
- Helm will use these files to create the Kubernetes objects and deploy the Node.js application to the Kubernetes cluster.
After a while, the `node-app-chart` will be deployed as shown below:
Let’s use Kubectl to get the created pods, Kubernetes Deployment, and Service:
Pods
To get all the created pods, use this command:
kubectl get pods
Kubernetes Deployment
To get the Kubernetes Deployment, use this command:
kubectl get deployment
Kubernetes Service
To get the Kubernetes Service, use this command:
kubectl get service
We will use the created Kubernetes service to access the application.
Accessing the Node.js Application using Kubernetes Service
To access the application, run this Minikube command:
minikube service node-app-chart
Minikube will start a tunnel for `node-app-chart` and assign a unique URL to the application as shown below:
You can input the URL in your web browser to access the application:
From the image above, you can see that our Node.js application runs inside the Kubernetes Cluster. We have successfully deployed this application using Helm and Helm Chart.
Conclusion
In this guide, we have learned how to deploy a Node.js application to Kubernetes using Helm and Helm Charts. Helm is a package manager for Kubernetes applications.
It helps developers get started with Kubernetes. It simplifies the process of deploying the Kubernetes application. You only need to modify the YAML files once you have created a Helm Chart. Charts. Thank you all for reading, and Happy Helming!