Inteliny
DevOpsLevel: Intermediate15m•Verified Production Blueprint

How to Deploy a Kubernetes Cluster for Node.js Applications

Learn how to containerize, deploy, scale, and manage production-ready Node.js applications on local and AWS EKS Kubernetes clusters.

Inteliny Engineering

Principal Architect

Overview & Architecture Scope

Deploying Node.js applications to a Kubernetes cluster provides automated scaling, zero-downtime rolling updates, and resilient orchestration essential for modern cloud-native architectures. This guide covers containerizing a Node.js microservice, creating Kubernetes manifests, configuring auto-scaling, and deploying to AWS EKS. Whether you are running local environments with Minikube or setting up enterprise cloud infrastructure, following these steps ensures optimal availability and maintainability.

Prerequisites & System Requirements

Ensure your development workstation or staging server fulfills the following prerequisites before initiating commands:

Node.js v18.0+ runtime environment
MongoDB v6.0+ database cluster
Active AWS or Cloudflare account with DNS access
Linux Ubuntu 22.04 LTS server instance
Basic knowledge of CLI bash & Git workflow

Target System Architecture Diagram

Browser
NGINX
Node / Express
MongoDB / Redis

Interactive Execution Checklist

0/7 Completed

Step-by-Step Implementation Guide

1

Step 1: Containerize the Node.js Application

Create an optimized multi-stage Dockerfile for your Node.js application to ensure lean production images. Use an official Node.js Alpine base image, set environment variables, install dependencies, and expose the target application port.

Execute Command Terminal:

dockerfile
FROM node:18-alpine AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

FROM node:18-alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app ./ 
USER node
EXPOSE 3000
CMD ["node", "server.js"]
Using multi-stage builds reduces container size significantly and reduces attack surfaces by excluding unnecessary dev dependencies.
2

Step 2: Initialize Local Kubernetes Cluster with Minikube

Start a local cluster using Minikube to test configurations locally before cloud deployment. Verify that kubectl is pointed to your active local cluster context.

Execute Command Terminal:

bash
minikube start --driver=docker --cpus=4 --memory=8192
kubectl cluster-info
kubectl get nodes
Ensure Docker Desktop or a compatible container runtime is active on your host machine prior to starting Minikube.
3

Step 3: Define ConfigMaps and Secrets for Application Configuration

Separate configuration settings and sensitive credentials from application source code using Kubernetes ConfigMap and Secret resources.

Execute Command Terminal:

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nodejs-config
data:
  NODE_ENV: "production"
  PORT: "3000"
---
apiVersion: v1
kind: Secret
metadata:
  name: nodejs-secret
type: Opaque
stringData:
  DB_CONNECTION_STRING: "mongodb://user:pass@mongo-service:27017/appdb"
Always base64 encode or use secret management tools like HashiCorp Vault or AWS Secrets Manager for production environments.
4

Step 4: Create Deployment and Service Manifests

Define a Kubernetes Deployment to maintain application pods along with readiness/liveness probes, and expose it via a ClusterIP Service for internal networking.

Execute Command Terminal:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nodejs-app
  template:
    metadata:
      labels:
        app: nodejs-app
    spec:
      containers:
      - name: nodejs-container
        image: myregistry/nodejs-app:1.0.0
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: nodejs-config
        - secretRef:
            name: nodejs-secret
        livenessProbe:
          httpGet:
            path: /healthz
            port: 3000
          initialDelaySeconds: 15
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: nodejs-service
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 3000
  selector:
    app: nodejs-app
Health checks via liveness and readiness probes prevent unhealthy pods from receiving user traffic.
5

Step 5: Configure Ingress for HTTP/HTTPS Routing

Deploy an NGINX Ingress Controller to route external HTTP and HTTPS traffic directly to the internal Node.js service using custom paths or domain names.

Execute Command Terminal:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nodejs-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nodejs-service
            port:
              number: 80
Enable the Ingress addon in Minikube using `minikube addons enable ingress` before applying this configuration.
6

Step 6: Configure Horizontal Pod Autoscaler (HPA)

Implement automated dynamic scaling based on CPU or memory usage using Horizontal Pod Autoscaler.

Execute Command Terminal:

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nodejs-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nodejs-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
HPA requires a running Metrics Server in the Kubernetes cluster to query resource statistics.
7

Step 7: Deploy Cluster to AWS EKS

Provision a production-ready AWS Elastic Kubernetes Service (EKS) cluster using eksctl and deploy your configured application objects.

Execute Command Terminal:

bash
eksctl create cluster \
  --name production-node-cluster \
  --region us-east-1 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 3 \
  --nodes-min 2 \
  --nodes-max 5 \
  --managed

kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
Verify AWS CLI credentials and permissions before initiating EKS cluster creation commands.

Pro Tips & Optimizations

Always set strict memory and CPU requests/limits on container definitions to prevent noisy-neighbor issues.
Use non-root users (`USER node`) inside Docker containers to enforce security best practices.
Implement graceful shutdown handling (`process.on('SIGTERM')`) in Node.js to close active database connections during updates.
Utilize Helm charts to manage and version Kubernetes configuration manifests across environments.

Common Pitfalls to Avoid

Missing readiness and liveness probes, causing Kubernetes to route traffic to containers that are booting or deadlocked.
Hardcoding secret keys directly in Deployment YAML manifests instead of using Kubernetes Secrets.
Forgetting to define resource requests, which prevents Horizontal Pod Autoscaler from accurately evaluating resource metrics.
Conclusion & Next Steps

You have successfully configured, deployed, and scaled a Node.js application across both local and enterprise-grade AWS EKS Kubernetes clusters. By incorporating health checks, secrets management, dynamic horizontal autoscaling, and ingress routing, your Node.js application is equipped for resilient, zero-downtime production operations. To extend this setup, integrate CI/CD workflows using GitHub Actions or ArgoCD for continuous delivery.

Production Best Practices & Hardening

Security Hardening

Disable root SSH access, enforce key-based auth, and enable UFW firewall on ports 80/443.

Memory Management

Set Node.js max-old-space-size to 80% of total RAM to avoid Linux OOM-killer crashes.

Frequently Asked Questions

Yes, all NGINX, Docker, and PM2 deployment steps can be packaged into Infrastructure as Code (IaC) playbooks.

Need Help Implementing This?

Partner with Inteliny's principal architects to audit your stack, automate CI/CD, and accelerate deployment.

How to Deploy a Kubernetes Cluster for Node.js Applications | Inteliny Knowledge Base