Skip to content
Youngho Chaa cha cha

Deploy a Node.js app in a docker container to a Kubernetes cluster

node.js, docker, kubernetes3 min read

Minikube is a lightweight Kubernetes approach to run a simple cluster with only one node to test our applications. Minikube is available for Linux, macOS, and Windows systems.

Install required tools.

  • Install Docker:
  • Install kubectl:
  • Install a Kubernetes cluster like minikube (for local development):
brew install minikube
minikube start
😄 minikube v1.29.0 on Darwin 13.2.1 (arm64)
✨ Automatically selected the docker driver
📌 Using Docker Desktop driver with root privileges
👍 Starting control plane node minikube in cluster minikube
🚜 Pulling base image ...
💾 Downloading Kubernetes v1.26.1 preload ...
> preloaded-images-k8s-v18-v1...: 330.51 MiB / 330.51 MiB 100.00% 24.18 M
> 368.75 MiB / 368.75 MiB 100.00% 10.16 M
🔥 Creating docker container (CPUs=2, Memory=6100MB) ...
🐳 Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔗 Configuring bridge CNI (Container Networking Interface) ...
▪ Using image
🔎 Verifying Kubernetes components...
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
brew install kubectl
kubectl cluster-info dump

Create a dummy Node.js Express application

Create a project and install packages

mkdir nodejs-docker-kubernetes
code nodejs-docker-kubernetes
npm init -y
Wrote to ../nodejs-docker-kubernetes/package.json:
"name": "nodejs-docker-kubernetes",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"keywords": [],
"author": "",
"license": "ISC"
yarn add express

Set up TypeScript for the project

yarn add -D typescript ts-node @types/node @types/express
// tsconfig.json
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
"include": ["src"],
"exclude": ["node_modules"]

Create app.ts for the application and add run scripts to package.json

import express, { Request, Response } from 'express';
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Hello World!');
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
"scripts": {
"start": "ts-node src/app.ts",
"build": "tsc"

And run the service: yarn start

Build the Docker image and test-run it

Create a Dockerfile for the Node.js application:

FROM node:18
ENV NODE_ENV development
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "node", "app.js" ]

Build the docker image and run a Docker container using the image. It should show “Hello World!” in the GET request: http://localhost:8080/

docker build -t nodejs-docker-k8s .
docker run -d -p 8080:3000 --name nodejs-docker-k8s nodejs-docker-k8s

Deploy the image to Kubernetes cluster

Push the docker image to a container registry

docker login
docker tag nodejs-docker-k8s username/nodejs-docker-k8s
docker push username/nodejs-docker-k8s

Create Kubernetes deployment and service files

// deployment.yml
apiVersion: apps/v1
kind: Deployment
name: nodejs-docker-k8s
replicas: 1
app: nodejs-docker-k8s
app: nodejs-docker-k8s
- name: nodejs-docker-k8s
image: nodejs-docker-k8s
- containerPort: 3000
// service.yml
apiVersion: v1
kind: Service
name: nodejs-docker-k8s
app: nodejs-docker-k8s
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer

Start Kubernetes cluster and apply the Kubernetes deployment and service

minikube start
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
© 2024 by Youngho Chaa cha cha. All rights reserved.
Theme by LekoArts