Deploying JavaScript (Node.js) on Kubernetes: A Practical Basic Guide
Modern web development is unthinkable without containerization and orchestration. If you write in JavaScript (Node.js), sooner or later the question will arise: how to reliably run an application in production, ensure its scaling and fault tolerance? The answer is Kubernetes. It is not just a trendy tool, but the de facto standard for managing containerized applications.
In this guide, we will walk through the full deployment cycle of a simple Node.js application on Kubernetes. You will learn how to package code into a Docker image, create the necessary manifests, and run everything in a cluster. The material is intended for developers who are already familiar with the basics of Node.js and want to master DevOps practices.
1. Preparing the Node.js Application for Containerization
Before deploying an application to Kubernetes, it needs to be packaged into a container. To do this, we will create a simple Express application. Make sure you have Node.js and npm installed.
Create a file app.js:
const express = require('express');const app = express();const port = process.env.PORT || 3000;
app.get('/', (req, res) => { res.json({ message: 'Hello from Node.js on Kubernetes!' });});
app.get('/health', (req, res) => { res.status(200).send('OK');});
app.listen(port, () => { console.log(`Server running on port ${port}`);});It is important to add the /health endpoint — Kubernetes will use it for liveness probes.
Now let's create a Dockerfile in the project root:
FROM node:18-alpine
WORKDIR /usr/src/app
COPY package*.json ./RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]Build the image and test it locally:
docker build -t my-node-app:latest .docker run -p 3000:3000 my-node-app:latestOpen http://localhost:3000 — you should see a JSON response.
2. Basic Kubernetes Manifests for Node.js
Kubernetes works with declarative configurations (YAML). To deploy a Node.js application, we will need at least two main resources: Deployment and Service.
2.1. Deployment
A Deployment manages the replicas of your application. Create a file deployment.yaml:
apiVersion: apps/v1kind: Deploymentmetadata: name: node-app-deployment labels: app: node-appspec: replicas: 3 selector: matchLabels: app: node-app template: metadata: labels: app: node-app spec: containers: - name: node-app image: my-node-app:latest ports: - containerPort: 3000 env: - name: PORT value: "3000" livenessProbe: httpGet: path: /health port: 3000 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 3 periodSeconds: 5Important points:
replicas: 3— Kubernetes will create 3 copies of your application for fault tolerance.livenessProbe— checks if the application is alive. If there is no response, Kubernetes will restart the container.readinessProbe— checks if the application is ready to accept traffic. Until the check passes, the pod does not receive requests.
2.2. Service
A Service provides network access to the pods. Create service.yaml:
apiVersion: v1kind: Servicemetadata: name: node-app-servicespec: selector: app: node-app ports: - protocol: TCP