How to Deploy and Run Node-js Rest API on Minikube

Minikube is a tool that runs a single-node Kubernetes cluster in a virtual machine on your personal computer. We are going to deploy and run NodeJS rest API on MInikube in this article. First, we create an API and run it normally, then we will run the same on the Docker and, finally, we create a deployment and service objects to deploy and run it on Kubernetes locally.

We are going to need some pre-requisites to complete this project or run it on your local machine.

Example Project

Since this post is all about how we can run NodeJS API on local Kubernetes we are not going to focus much on API itself.

Here is a simple NodeJS API with two routes / and /name:myname returnsHello World and returning whatever the name you entered respectively.

const http = require('http');
const qs = require("querystring");
const url = require('url');

const port = process.env.PORT || 3000

const server = http.createServer((req, res) => {

    if (req.method !== 'GET') handleError(405, res);

    const {pathname, query} = url.parse(req.url);

    if (pathname === '/name') {
        const {name} = qs.parse(query);
        if (name) {
            res.end(`<h1>You Entered: ${name.toUpperCase()}</h1>`)
        } else {
            res.end("Bad Request");
        }
        
    }

    if (pathname === '/') {
        res.end(`<h1>Hello World</h1>`)
    }
});

function handleError(code, res) {
    res.statusCode = code;
    res.end(`{"error": "${http.STATUS_CODES[code]}"}`);
}

server.listen(port, () => {
    console.log(`Server listening on port ${port}`);
});

index.js

Here is the Github link. You can clone it and run it on your machine

// clone it
git clone https://github.com/bbachi/nodejs-restapi-minikube.git

// install and start the project
npm install
npm start

Run it On Docker

Docker is a container runtime that Kubernetes uses. You can use another container runtime but the Docker is most popular for now. Let’s run this Node API on Docker. We need to define Dockerfile first which is used to automate the Docker image creation. Docker builds images by reading instructions from the Dockerfile.

Here is the Dockerfile for this project. We are building the image from base image node:10 and copying the package.json to install all the dependencies. Copying just package.json to install all the dependencies is one of the best practices. Docker builds images from the layers in the cache. We don’t want to repeat installing if there is a change in the index.js.

# stage1 as builder
FROM node:10-alpine

WORKDIR /api

COPY . .

EXPOSE 3000

ENTRYPOINT ["node", "index.js"]

Dockerfile

Let’s build the image and run it on docker with these instructions.

// building the image
docker build -t node-api .

// list images
docker images

// Run the container
docker run -d --name nodeapi -p 3000:3000 node-api

Once you run the above commands you can hit these URLs in the browser. You can exec into a running container and see the file system inside the container.

// urls
http://localhost:3000/name?name=somename
http://localhost:3000/

// exec into the running container
docker exec -it nodeapi /bin/sh

Create a Deployment and Service Objects

A pod is a group of one or more containers that share the storage and network and has the specification on how to run the container. You can check the pod documentation here.

Running Local images on Minikube

Kubernetes always try to pull images from the Docker registry. If you want to use your local docker images you need to do certain steps on your local machine.

// set the environment
eval $(minikube docker-env)

// build the image
docker build -t node-api .

// list the images
docker images

Let’s create a pod with the below file. Before that, You need to start the Minikube on your local machine with this command minikube start and create a pod with this kubectl create -f pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: node-api-pod
spec:
  containers:
    - image: node-api
      name: node-api
      imagePullPolicy: Never
      resources: {}
      ports:
        - containerPort: 3000

pod.yml

You can exec into the file system with this command kubectl exec -it node-api-pod .bin/sh

exec into a running pod

Deployment

Creating just one pod is not enough and what if you want to scale out the application and want to run 10 replicas at the same time. What if you want to change the number of replicas depending on the demand. That’s where the deployment comes into the picture. We specify the desired state in the deployment object such as how many replicas you want to run etc.

Kubernetes makes sure that it always meets the desired state. It creates replica sets which inturn creates pods in the background. Let’s create a Deployment for our project with this command kubectl create -f deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nodeapi
  name: nodeapi
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nodeapi
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nodeapi
    spec:
      containers:
      - image: node-api
        name: node-api
        imagePullPolicy: Never
        resources: {}
        ports:
          - containerPort: 3000 
status: {}

deployment.yml

We have 5 replicas in the specification and the deployment creates 5 pods and 1 replica set.

deployment

Service

Service is an abstract way to expose an application running on a set of Pods as a network service. Let’s create a service with type NodePort so that we can access the nodejs API from the browser. Here is the service object YAML

apiVersion: v1
kind: Service
metadata:
  name: nodeapi
  labels:
    run: nodeapi
spec:
  ports:
  - port: 3000
    protocol: TCP
  selector:
    app: nodeapi
  type: NodePort

service.yml

Create a service with this command kubectl create -f service.yml and you can list the service with this kubectl get svc

Running services

How to access deployment from the browser

We have created deployment and services and now we need to access this deployment from the browser.

We need to get the public IP address of the Kubernetes with this command kubectl cluster-info

master is running at 192.168.64.2

Get the port from the service object that we just created with this command kubectl get svc

service is listening on port 32329

Let’s access the nodejs API with this IP address 192.168.64.2 and port 32329 with the below URLs. Make sure that you use Http instead of Https.

// endpoints port and IP address might change

http://192.168.64.2:32329/name?name=myname

http://192.168.64.2:32329/

Here is the result

Accessing API in the browser

Conclusion

It’s always convenient to use Minikube and own docker images for the local testing. We don’t even deploy in some kind of environment to test our workflow.

Thank you for reading!

#node-js #docker #kubernetes #rest-api #webdev

How to Deploy and Run Node-js Rest API on Minikube
1 Likes32.50 GEEK