DEV Community

Cover image for πŸ’¨ The fastest way to deploy your Javascript app to Kubernetes 🌬️ ✨
Eden Federman for Odigos

Posted on

πŸ’¨ The fastest way to deploy your Javascript app to Kubernetes 🌬️ ✨

TL;DR

In this tutorial, you'll learn how to deploy your first javascript application on Kubernetes - a container orchestration platform ☸️.

We will deploy a simple express server that returns a sample JSON object on Kubernetes locally using Minikube ✨.

Prerequisites πŸ“œ:

  • Docker: For containerizing the application. πŸ‹
  • Minikube: For running Kubernetes locally. ☸️

GetADeploy


Odigos - Open-source Distributed Tracing

Monitor all your apps simultaneously without writing a single line of code!
Simplify OpenTelemetry complexity with the only platform that can generate distributed tracing across all your applications.

We are really just starting out.

Can you help us with a star? Plz? 😽

Cats


Let's set it up πŸš€

We'll start by initializing our project with:

npm init -y
Enter fullscreen mode Exit fullscreen mode

This initializes a NodeJS project with the package.json πŸ“ file which keeps track of our installed dependencies.

Install Express.js framework

npm install express
Enter fullscreen mode Exit fullscreen mode

Now, inside the package.json the dependencies object should look something like this. βœ…

  "dependencies": {
    "express": "^4.18.2"
  }
Enter fullscreen mode Exit fullscreen mode

Now, at the root of the project create an index.js file and add the following lines of code. πŸš€

// πŸ‘‡πŸ» Initialize express.
const express = require("express");
const app = express();

const port = 3000;

// πŸ‘‡πŸ» Return a sample JSON object with a message property on the root path.
app.get("/", (req, res) => {
  res.json({
    message: "Hello from Odigos!",
  });
});

// πŸ‘‡πŸ» Listen on port 3000.
app.listen(port, () => {
  console.log(`Server is listening on port ${port}`);
});
Enter fullscreen mode Exit fullscreen mode

We need to add a script in our package.json for running the application. Add it within the scripts object of package.json.

  "scripts": {
    "dev": "node index.js"
  },
Enter fullscreen mode Exit fullscreen mode

Now, to check our application is running properly, run the server using npm run dev and make a get request to localhost:3000 either via CLI or in the browser. ✨

If you are using CLI, make sure to have cURL installed. βœ…

curl http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

You should see something like this. πŸ‘‡πŸ»

cURL response

Now, you can simply stop the running express server using Ctrl + C 🚫

Our sample application is ready! πŸŽ‰ Now, let's containerize it and push it to Kubernetes. 🐳☸️


Containerize the application πŸ“¦

We will be using Docker to containerize our application.
In the root of the project, create a new file named Dockerfile.

πŸ’‘ Make sure to exactly name it the same. Otherwise, you will need to explicitly pass the -f flag for specifying the Dockerfile path.

# Uses node as the base image
FROM node:21-alpine 
# Sets up our working directory as /app inside the container.
WORKDIR /app
# Copyies package json files.
COPY package.json package-lock.json ./
# Installs the dependencies from the package.json
RUN npm install --production
# Copies current directory files into the docker environment
COPY . .
# Expose port 3000 as our server uses it.
EXPOSE 3000
# Finally runs the server.
CMD ["node", "index.js"]
Enter fullscreen mode Exit fullscreen mode

Now, we need to build βš’οΈ this container to be able to actually use it and push it to Kubernetes.

Run this command to build the Dockerfile.

🚨 If you are running it on Windows, make sure to have Docker Desktop running.

// πŸ‘‡πŸ» We are tagging our image name to express-server
docker build -t express-server .
Enter fullscreen mode Exit fullscreen mode

Now, it's time to run the container. πŸƒπŸ»β€β™‚οΈπŸ’¨

docker run -dp 127.0.0.1:3000:3000 express-server
Enter fullscreen mode Exit fullscreen mode

πŸ’‘ We are running our container in the background with the container port 3000 mapping to our computer port 3000.

Once again run the following command and you should see the same result as earlier. βœ…

curl http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

NOTE: This time the application is not running on our computer as before. Instead, it is running inside the container. 🀯


Deploying in Kubernetes βš“

As said earlier, we will use Minikube to create an orchestration environment in our local computer and use kubectl command to interact with Kubernetes. πŸ˜„

Start Minikube: πŸš€

minikube start
Enter fullscreen mode Exit fullscreen mode

Since we are going to be using local containers instead of pulling them from the docker hub, run these commands. ✨

eval $(minikube docker-env)
docker build -t express-server .
Enter fullscreen mode Exit fullscreen mode

eval $(minikube docker-env): It is used to point your terminal’s docker-cli to the Docker Engine inside minikube.

🚨 Note, many of us use Fish as our shell, so for fish the corresponding command would be eval (minikube docker-env)

Now, in the project root, create a nested folder k8/deployment, and inside the deployment folder, create a new file called deployment.yaml with the following content.

In this file, we will manage the deployment of our container. πŸ‘‡πŸ»

# πŸ‘‡πŸ» /k8/deployment/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: express-deployment
spec:
  selector:
    matchLabels:
      app: express-svr
  template:
    metadata:
      labels:
        app: express-svr
    spec:
      containers:
        - name: express-svr
          image: express-server
          imagePullPolicy: Never # Make sure to set it to Never, or else it will pull from the docker hub and fail.
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
          ports:
            - containerPort: 3000
Enter fullscreen mode Exit fullscreen mode

Finally, run this command to apply the deployment configuration we just created, deployment.yaml. ✨

kubectl apply -f .\k8\deployment\deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Now, if we take a look at the running pods we can see that the pod has successfully been created. πŸŽ‰

running kubernetes pods

To view the logs of our created pod, run kubectl logs <pod_name> and we should see the following.

logs of the running kubernetes pod

With this, our express-server is successfully deployed on a local Kubernetes. 😎


That is it for this article, we successfully containerized our application and deployed it to Kubernetes.

The source code for this article can be found here
https://github.com/keyval-dev/blog/tree/main/js-on-k8s

Thank you so much for reading! πŸŽ‰πŸ«‘

Top comments (6)

Collapse
 
kehoecj profile image
Clayton Kehoe

Great guide!

Collapse
 
gschaden profile image
Gerhard Schaden • Edited

COPY . .
Is a very bad idea as you copy too much of your project into the container. e g. All . files like .git .vscode are copied to the docker container and lead to size and security concernes.
You should ONLY copy what's really needed.

Collapse
 
qainsights profile image
NaveenKumar Namachivayam ⚑

Thanks for the guide. You are running containers as root (not recommended), instead you can create a USER and start the process :)

Collapse
 
syamsiva12 profile image
Shyam prasad

Yes. It run as root but not like root as the underlying host.U can say it like shadow of root with limited privileges. U can add previlage using cap flag. If u want the container run as root as the underlying host u need to specify --previlaged flag along with the docker commands.

Collapse
 
takmanjim profile image
takmanjim

Great!!!

Collapse
 
shricodev profile image
Shrijal Acharya

Great read! πŸ”₯ I am always amazed by how good Kubernetes is! πŸš€