Introduction to Docker and Kubernetes with Node.js

RMAG news

Hey devs!

With the growing adoption of microservices and the need for scalability, Docker and Kubernetes have become indispensable technologies. While Docker facilitates the creation and management of containers, Kubernetes orchestrates these containers in a cluster, providing high availability and scalability. Let’s explore how to use Docker and Kubernetes to deploy a Node.js application.

Prerequisites

Basic knowledge of Docker and Kubernetes
Node.js installed
Docker installed
Minikube (or another Kubernetes environment) configured

Project Structure

Let’s create a simple Node.js project with the following folder structure:

my-node-app/
├── src/
└── index.js
├── Dockerfile
├── .dockerignore
├── package.json
└── k8s/
├── deployment.yaml
├── service.yaml
└── ingress.yaml

Step 1: Setting Up the Node.js Application

First, let’s create the Node.js application.

package.json File
Create the package.json file with the following content:

{
“name”: “my-node-app”,
“version”: “1.0.0”,
“description”: “A simple Node.js app”,
“main”: “src/index.js”,
“scripts”: {
“start”: “node src/index.js”
},
“dependencies”: {
“express”: “^4.17.1”
}
}

src/index.js File
Create the src directory and, inside it, the index.js file with the following content:

const express = require(express);
const app = express();
const port = 3000;

app.get(/, (req, res) => {
res.send(Hello World!);
});

app.listen(port, () => {
console.log(`App running on http://localhost:${port}`);
});

Step 2: Dockerizing the Application

Dockerfile
Create a Dockerfile in the root of the project with the following content:

# Use the official Node.js base image
FROM node:14

# Create a working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the application port
EXPOSE 3000

# Command to start the application
CMD [“npm”, “start”]

.dockerignore File
Create a .dockerignore file in the root of the project to prevent unnecessary files from being copied to the container:

node_modules
npm-debug.log

Building and Running the Container
To build and run the container, execute the following commands:

docker build -t my-node-app .
docker run -p 3000:3000 my-node-app

Step 3: Orchestrating with Kubernetes

Let’s create the Kubernetes manifests to deploy the application in a cluster.

k8s/deployment.yaml File
Create the k8s directory and, inside it, the deployment.yaml file with the following content:

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-node-app
spec:
replicas: 2
selector:
matchLabels:
app: my-node-app
template:
metadata:
labels:
app: my-node-app
spec:
containers:
name: my-node-app
image: my-node-app:latest
ports:
containerPort: 3000

k8s/service.yaml File
Create the service.yaml file in the k8s directory with the following content:

apiVersion: v1
kind: Service
metadata:
name: my-node-app-service
spec:
selector:
app: my-node-app
ports:
protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer

Deploying to Kubernetes
To deploy the application to Kubernetes, execute the following commands:

kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml

Check if the pods are running:

kubectl get pods

And the service:

kubectl get services

The service should display an external IP address where the application will be available.

Step 4: Setting Up Ingress in Kubernetes

To expose the application using an Ingress resource, we need to configure an Ingress controller and create an Ingress resource.

Enabling the Ingress Controller in Minikube
Enable the Ingress controller in Minikube with the following command:

minikube addons enable ingress

k8s/ingress.yaml File
Create the ingress.yaml file in the k8s directory with the following content:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-node-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
host: my-node-app.local
http:
paths:
path: /
pathType: Prefix
backend:
service:
name: my-node-app-service
port:
number: 80

Deploying the Ingress Resource
Apply the Ingress resource to the cluster:

kubectl apply -f k8s/ingress.yaml

Testing the Ingress
To test the Ingress, add an entry to your /etc/hosts file to map my-node-app.local to the Minikube IP. Get the Minikube IP with:

minikube ip

Then, add the following line to your /etc/hosts file:

<minikubeip> mynodeapp.local

Replace with the actual IP address returned by the minikube ip command.

Now, you should be able to access the application at http://my-node-app.local.

Conclusion

In this post, we created a simple Node.js application, dockerized it, deployed it to a Kubernetes cluster, and exposed it using an Ingress resource. Docker and Kubernetes are powerful tools that, when combined, provide an efficient way to manage and scale applications. With these tools, you can ensure that your applications are always available and easily scalable as needed.