Ashish Singh
System Weakness
Published in
3 min readJan 12, 2024

--

Deploying a 3-tier architecture with Kubernetes for a MERN (MongoDB, Express.js, React, Node.js) application involves setting up separate containers or pods for each tier of your application.

I’ll provide simplified examples for each step using YAML files. Please note that these examples are meant for educational purposes and may need modification based on your specific requirements.

Step 1: Dockerize Each Component

MongoDB Dockerfile

# Dockerfile for MongoDB

FROM mongo:latest
# Additional configurations if needed
$ docker build -t your-registry/mongo:latest -f path/to/MongoDB/Dockerfile .
$ docker push your-registry/mongo:latest

Node.js/Express.js Dockerfile

# Dockerfile for Node.js/Express.js

FROM node:latest
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "server.js"]
$ docker build -t your-registry/express:latest -f path/to/Express.js/Dockerfile .
$ docker push your-registry/express:latest

React Dockerfile

# Dockerfile for React

FROM node:latest as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:latest
COPY - from=build /app/build /usr/share/nginx/html
$ docker build -t your-registry/react:latest -f path/to/React/Dockerfile .
$ docker push your-registry/react:latest

Step 2: MongoDB Deployment

mongodb-deployment.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo:latest
ports:
- containerPort: 27017
name: mongodb
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 1Gi

mongodb-service.yaml

apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
$ kubectl apply -f path/to/MongoDB/mongodb-deployment.yaml
$ kubectl apply -f path/to/MongoDB/mongodb-service.yaml

Step 3: Node.js/Express.js Deployment

express-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: express
spec:
replicas: 2
selector:
matchLabels:
app: express
template:
metadata:
labels:
app: express
spec:
containers:
- name: express
image: your-registry/express:latest
ports:
- containerPort: 3000
env:
- name: MONGODB_URI
value: "mongodb://mongodb:27017/yourdb"
---
apiVersion: v1
kind: Service
metadata:
name: express
spec:
selector:
app: express
ports:
- protocol: TCP
port: 3000
targetPort: 3000
$ kubectl apply -f path/to/Express.js/express-deployment.yaml

Step 4: React Deployment

react-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: react
spec:
replicas: 2
selector:
matchLabels:
app: react
template:
metadata:
labels:
app: react
spec:
containers:
- name: react
image: your-registry/react:latest
ports:
- containerPort: 80
env:
- name: REACT_APP_API_URL
value: "http://express:3000"
---
apiVersion: v1
kind: Service
metadata:
name: react
spec:
selector:
app: react
ports:
- protocol: TCP
port: 80
targetPort: 80
$ kubectl apply -f path/to/React/react-deployment.yaml

Step 5: Ingress Controller

nginx-ingress-controller.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress-controller
template:
metadata:
labels:
app: nginx-ingress-controller
spec:
containers:
- name: nginx-ingress-controller
image: nginx/nginx-ingress:latest
---
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller
spec:
selector:
app: nginx-ingress-controller
ports:
- protocol: TCP
port: 80
targetPort: 80
$ kubectl apply -f path/to/Nginx/nginx-ingress-controller.yaml

ingress-resource.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- host: your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: react
port:
number: 80
$ kubectl apply -f path/to/Ingress/ingress-resource.yaml

Step 6: Verify Deployments

Verify that the deployments are running successfully:

# Check StatefulSet and Service for MongoDB
$ kubectl get statefulset mongodb
$ kubectl get service mongodb
# Check Deployment and Service for Express.js
$ kubectl get deployment express
$ kubectl get service express
# Check Deployment and Service for React
$ kubectl get deployment react
$ kubectl get service react
# Check Nginx Ingress Controller
$ kubectl get deployment nginx-ingress-controller
$ kubectl get service nginx-ingress-controller
# Check Ingress Resource
$ kubectl get ingress my-ingress

Step 7: Access Your Application

Access your MERN application through the defined Ingress resource. The URL will depend on your Ingress controller and the domain you specified in the Ingress resource.

For example, if you used your-domain.com in the Ingress resource:

Ensure that DNS is configured to resolve the specified domain to your Ingress controller’s external IP or domain.

These examples are simplified, and you might need to customize them according to your application’s specifics. Additionally, consider using Helm charts for more complex deployments and better maintainability.

--

--