Hey devs!
With the growing adoption of microservices and the need for scalability, Docker and Kubernetes have become indispensable technologies. While Docker facilitates the creation and management of containers, Kubernetes orchestrates these containers in a cluster, providing high availability and scalability. Let's explore how to use Docker and Kubernetes to deploy a Node.js application.
Prerequisites
- Basic knowledge of Docker and Kubernetes
- Node.js installed
- Docker installed
- Minikube (or another Kubernetes environment) configured
Project Structure
Let's create a simple Node.js project with the following folder structure:
my-node-app/
├── src/
│ └── index.js
├── Dockerfile
├── .dockerignore
├── package.json
└── k8s/
├── deployment.yaml
├── service.yaml
└── ingress.yaml
Step 1: Setting Up the Node.js Application
First, let's create the Node.js application.
package.json File
Create the package.json file with the following content:
{
"name": "my-node-app",
"version": "1.0.0",
"description": "A simple Node.js app",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js"
},
"dependencies": {
"express": "^4.17.1"
}
}
src/index.js File
Create the src directory and, inside it, the index.js file with the following content:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`App running on http://localhost:${port}`);
});
Step 2: Dockerizing the Application
Dockerfile
Create a Dockerfile in the root of the project with the following content:
# Use the official Node.js base image
FROM node:14
# Create a working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code
COPY . .
# Expose the application port
EXPOSE 3000
# Command to start the application
CMD ["npm", "start"]
.dockerignore File
Create a .dockerignore file in the root of the project to prevent unnecessary files from being copied to the container:
node_modules
npm-debug.log
Building and Running the Container
To build and run the container, execute the following commands:
docker build -t my-node-app .
docker run -p 3000:3000 my-node-app
Step 3: Orchestrating with Kubernetes
Let's create the Kubernetes manifests to deploy the application in a cluster.
k8s/deployment.yaml File
Create the k8s directory and, inside it, the deployment.yaml file with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-node-app
spec:
replicas: 2
selector:
matchLabels:
app: my-node-app
template:
metadata:
labels:
app: my-node-app
spec:
containers:
- name: my-node-app
image: my-node-app:latest
ports:
- containerPort: 3000
k8s/service.yaml File
Create the service.yaml file in the k8s directory with the following content:
apiVersion: v1
kind: Service
metadata:
name: my-node-app-service
spec:
selector:
app: my-node-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Deploying to Kubernetes
To deploy the application to Kubernetes, execute the following commands:
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
Check if the pods are running:
kubectl get pods
And the service:
kubectl get services
The service should display an external IP address where the application will be available.
Step 4: Setting Up Ingress in Kubernetes
To expose the application using an Ingress resource, we need to configure an Ingress controller and create an Ingress resource.
Enabling the Ingress Controller in Minikube
Enable the Ingress controller in Minikube with the following command:
minikube addons enable ingress
k8s/ingress.yaml File
Create the ingress.yaml file in the k8s directory with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-node-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: my-node-app.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-node-app-service
port:
number: 80
Deploying the Ingress Resource
Apply the Ingress resource to the cluster:
kubectl apply -f k8s/ingress.yaml
Testing the Ingress
To test the Ingress, add an entry to your /etc/hosts file to map my-node-app.local to the Minikube IP. Get the Minikube IP with:
minikube ip
Then, add the following line to your /etc/hosts file:
<minikube-ip> my-node-app.local
Replace with the actual IP address returned by the minikube ip command.
Now, you should be able to access the application at http://my-node-app.local.
Conclusion
In this post, we created a simple Node.js application, dockerized it, deployed it to a Kubernetes cluster, and exposed it using an Ingress resource. Docker and Kubernetes are powerful tools that, when combined, provide an efficient way to manage and scale applications. With these tools, you can ensure that your applications are always available and easily scalable as needed.
Top comments (2)
Thank you for the article,
I have this issue : W0807 12:08:51.239511 21900 main.go:291] Unable to resolve the current Docker CLI context "default": context "default": context not found: open C:\Users\Acer.docker\contexts\meta\37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f\meta.json: The system cannot find the path specified.
What might be the problem please ?
Thanks for sharing this. The final image size with your Dockerfile is huge though (858MB).
Can you suggest a multi-stage docker file to reduce the size?
Thanks