💨 The fastest way to deploy your Javascript app to Kubernetes 🌬️ ✨
Tags: webdev, programming, tutorial, devops
Published: 2023-11-14 12:24:54

## 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. 🐋

<br />

- **Minikube**: For running Kubernetes locally. ☸️


![GetADeploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mn162frk9shm0d76z99n.gif)

***

## 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.

{% cta https://github.com/keyval-dev/odigos %} Can you help us with a star? Plz? 😽 {% endcta %}


[![Cats](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84twzafd93w3a4ktqflm.png)](https://github.com/keyval-dev/odigos)

<hr />

### Let's set it up 🚀

We'll start by initializing our project with:

```bash
npm init -y
```

This initializes a **NodeJS** project with the `package.json` 📝 file which keeps track of our installed dependencies.

Install Express.js framework

```bash
npm install express
``` 

Now, inside the `package.json` the dependencies object should look something like this. ✅

```json
  "dependencies": {
    "express": "^4.18.2"
  }
```

Now, at the root of the project create an `index.js` file and add the following lines of code. 🚀

```javascript
// 👇🏻 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}`);
});
```

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

```json
  "scripts": {
    "dev": "node index.js"
  },
```


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](https://curl.se/) installed. ✅

```bash
curl http://localhost:3000
```

You should see something like this. 👇🏻

![cURL response](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxs2uu8u0aa7kw6k9ta4.png)

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.

```Dockerfile
# 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"]
```

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.

```bash
// 👇🏻 We are tagging our image name to express-server
docker build -t express-server .
```

Now, it's time to run the container. 🏃🏻‍♂️💨

```
docker run -dp 127.0.0.1:3000:3000 express-server
```

> 💡 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. ✅

```bash
curl http://localhost:3000
```

> **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: 🚀**

```bash
minikube start
```

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

```bash
eval $(minikube docker-env)
docker build -t express-server .
```

`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. 👇🏻

```yaml
# 👇🏻 /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
```

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

```bash
kubectl apply -f .\k8\deployment\deployment.yaml
```

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

![running kubernetes pods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83ijo09xpd9ccv30h6ug.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f97aap8qioqsjr45rafw.png)

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! 🎉🫡