Deploying a Node.js Application with Docker 🐳 and Kubernetes ☸ : A Beginner's Journey

Manu Arora

Bharat Kasera / May 30, 2025

4 min read

Containerization and orchestration can feel like rocket science at first glance, but once you break down the process, it's surprisingly approachable. In this guide, we'll walk through how to package a simple Node.js app into a Docker container, push it to Docker Hub, and then spin it up in a local Kubernetes cluster using Minikube — all with step-by-step clarity.


The Architecture in a Nutshell

The workflow is a straightforward two-stage pipeline:

  1. Build ➜ Push: Package your Node.js app into a Docker image and push it to Docker Hub.
  2. Deploy: In your local Kubernetes cluster (Minikube), apply two manifests:
    • Deployment – pulls the image, runs three replicas, and labels them.
    • Service – load-balances traffic on port 80 to each pod's port 3000.

By the end you'll have a scalable, highly-available app running in three pods behind a load balancer.


1. Dockerizing Your Node.js App

Imagine you've got a tiny Express server:

const express = require("express");
const app = express();

app.get("/", (req, res) =>
  res.send("Hello from Node.js app running in Kubernetes!")
);

app.listen(3000, () => console.log("Server listening on port 3000"));

a. Create a Dockerfile

FROM node:22-alpine          # 1. Start from a lightweight Node image
WORKDIR /usr/src/app         # 2. Set working directory
COPY package*.json ./        # 3. Copy dependency manifests
RUN npm install              # 4. Install dependencies
COPY . .                     # 5. Copy app source
EXPOSE 3000                  # 6. Declare runtime port
CMD ["node", "index.js"]     # 7. Startup command

b. Optimize with .dockerignore

node_modules
npm-debug.log

This keeps your image lean by excluding bulky folders and logs.

c. Build and Test Locally

# Build the image
docker build -t yourusername/node-k8s-tutorial:1.0 .

# Run it
docker run -d -p 3000:3000 yourusername/node-k8s-tutorial:1.0

# Verify
curl http://localhost:3000
# → "Hello from Node.js app running in Kubernetes!"

Once everything looks good, stop the container and move on.


2. Pushing to Docker Hub

# Log in
docker login -u yourusername

# Tag your image
docker tag node-k8s-tutorial:1.0 yourusername/node-k8s-tutorial:1.0

# Push it
docker push yourusername/node-k8s-tutorial:1.0

Your image now lives on Docker Hub, ready for Kubernetes to pull.


3. Setting Up a Local Kubernetes Cluster with Minikube

Minikube is a lightweight Kubernetes environment ideal for learning.

# Install (macOS example with Homebrew)
brew install minikube

# Start your cluster
minikube start

Kubernetes is now running on a VM or container on your machine.


4. Writing Kubernetes Manifests

We'll need two YAML files:

a. Deployment (deployment.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-deployment
spec:
  replicas: 3 # Run 3 pods
  selector:
    matchLabels:
      app: nodejs
  template:
    metadata:
      labels:
        app: nodejs
    spec:
      containers:
        - name: nodejs
          image: yourusername/node-k8s-tutorial:1.0
          ports:
            - containerPort: 3000

b. Service (service.yaml)

apiVersion: v1
kind: Service
metadata:
  name: nodejs-service
spec:
  type: LoadBalancer # Expose via a load-balancer
  selector:
    app: nodejs
  ports:
    - port: 80 # Cluster-wide port
      targetPort: 3000 # Pod's port

5. Deploying to Kubernetes

# Apply the deployment
kubectl apply -f deployment.yaml

# Apply the service
kubectl apply -f service.yaml

# Check status
kubectl get pods
kubectl get services

You should see three pods up and running, plus a service exposing them.


6. Accessing Your App

Minikube provides an easy way to get the external URL:

minikube service nodejs-service --url
# → http://<minikube-ip>:<port>

Paste that URL in your browser — voilà! Your Node.js app is live, load-balanced across three pods.


7. Next Steps & Tips

Scaling

kubectl scale deployment nodejs-deployment --replicas=5

Rolling Updates

Update your image tag in the deployment manifest and run:

kubectl apply -f deployment.yaml

Debugging

kubectl describe deployment nodejs-deployment
kubectl logs <pod-name>

By containerizing with Docker and orchestrating with Kubernetes, you've unlocked powerful deployment patterns: consistent builds, effortless scaling, and self-healing clusters. While this tutorial used Minikube for local learning, the same manifests work on any cloud-hosted Kubernetes service.

Play around, break things, and rebuild — each hiccup is a step toward mastery.


Happy deploying 😄!

Want to hire me? Let's discuss.

Drop your message and let's discuss about your project.

Chat on WhatsApp

Email me at