Skip to content

Commit

Permalink
Enhancement: MERN stack project for Kubernetes deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
Saurabhkr952 committed Oct 21, 2023
1 parent 64e11e7 commit 05d054d
Show file tree
Hide file tree
Showing 14 changed files with 432 additions and 19 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/backend cicd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Backend CI/CD

on:
push:
branches:
- main
paths:
- 'backend/**' # Trigger only for changes in the backend directory

jobs:
build-and-push-backend:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/[email protected]

- name: Build & push backend Docker image
uses: mr-smithers-excellent/docker-build-push@v6
with:
directory: backend
image: saurabhkr952/book-store-mern
tags: backend-${{ github.sha }}
registry: docker.io
dockerfile: backend/Dockerfile
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

update-kubernetes-manifest: # this job will update the kubernetes manifest files image version tag
runs-on: ubuntu-latest
needs:
- build-and-push-backend
steps:
- uses: actions/checkout@v3
with:
repository: saurabhkr952/Book-Store-MERN-Stack
ref: 'main'
token: ${{ secrets.PAT_TOKEN }}
- name: setup git config
run: |
git config --local user.email "[email protected]"
git config --local user.name "saurabhkr952"
echo ${{ github.sha }}
sed -i 's+saurabhkr952/book-store-mern:backend.*+saurabhkr952/book-store-mern:backend-${{ github.sha }}+g' kubernetes-manifests/2.backend.yaml
git add -A
git commit -m "update image tag for - ${{ github.sha }}"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.PAT_TOKEN }}
repository: saurabhkr952/Book-Store-MERN-Stack
force: true
54 changes: 54 additions & 0 deletions .github/workflows/frontend cicd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Frontend CI/CD

on:
push:
branches:
- main
paths:
- 'frontend/**' # Trigger only for changes in the frontend directory

jobs:
build-and-push-frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/[email protected]

- name: Build & push frontend Docker image
uses: mr-smithers-excellent/docker-build-push@v6
with:
directory: frontend
image: saurabhkr952/book-store-mern
tags: frontend-${{ github.sha }}
registry: docker.io
dockerfile: frontend/Dockerfile
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

update-kubernetes-manifest: # this job will update the kubernetes manifest files image version tag
runs-on: ubuntu-latest
needs:
- build-and-push-frontend
steps:
- uses: actions/checkout@v3
with:
repository: saurabhkr952/Book-Store-MERN-Stack
ref: 'main'
token: ${{ secrets.PAT_TOKEN }}
- name: setup git config
run: |
git config --local user.email "[email protected]"
git config --local user.name "saurabhkr952"
echo ${{ github.sha }}
sed -i 's+saurabhkr952/book-store-mern:frontend.*+saurabhkr952/book-store-mern:frontend-${{ github.sha }}+g' kubernetes-manifests/1.frontend.yaml
git add -A
git commit -m "update image tag for - ${{ github.sha }}"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.PAT_TOKEN }}
repository: saurabhkr952/Book-Store-MERN-Stack
force: true


# sed -i 's+saurabhkr952/book-store-mern:frontend-.*+saurabhkr952/book-store-mern:frontend-${{ github.sha }}+g' kubernetes-manifests/"1. frontend.yaml"
58 changes: 43 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
# Book Store MERN stack project
# Book Store MERN Stack Project

## Lessons

- [x] Lesson 01: Create Node.js project from scratch
- [x] Lesson 02: Create our first Http Route
- [x] Lesson 03: Add MongoDB and mongoose to node js
- [x] Lesson 04: Create Book model with mongoose
- [x] Lesson 05: Save a new Book with mongoose
- [x] Lesson 06: Get All Books with mongoose
- [x] Lesson 07: Get One Book by id with mongoose
- [x] Lesson 08: Update a Book with mongoose
- [x] Lesson 09: Delete a book with mongoose
- [x] Lesson 10: Refactor Node js with express router
- [x] Lesson 11: CORS policy in Node js and Express js
- [x] Lesson 12: Create React project, Vite, Tailwind CSS
- [x] Lesson 13: SPA and Add react router dom
- [x] Lesson 02: Create our first HTTP Route
- [x] Lesson 03: Add MongoDB and Mongoose to Node.js
- [x] Lesson 04: Create Book model with Mongoose
- [x] Lesson 05: Save a new Book with Mongoose
- [x] Lesson 06: Get All Books with Mongoose
- [x] Lesson 07: Get One Book by ID with Mongoose
- [x] Lesson 08: Update a Book with Mongoose
- [x] Lesson 09: Delete a Book with Mongoose
- [x] Lesson 10: Refactor Node.js with Express Router
- [x] Lesson 11: CORS Policy in Node.js and Express.js
- [x] Lesson 12: Create React Project, Vite, Tailwind CSS
- [x] Lesson 13: SPA and Add React Router DOM
- [x] Lesson 14: Show Books List in React
- [x] Lesson 15: Show Book Details in React
- [x] Lesson 16: Create Book in React
- [x] Lesson 17: Edit Book in React
- [x] Lesson 18: Delete Book in React
- [x] Lesson 19: Show Books List as Card
- [x] Lesson 20: Make Book Card a single component
- [x] Lesson 20: Make Book Card a Single Component
- [x] Lesson 21: Add Book Modal
- [x] Lesson 22: Improve User Experience (UX) with beautiful alert
- [x] Lesson 22: Improve User Experience (UX) with Beautiful Alert

## Recent Updates

### Kubernetes Deployment

In a recent update, I've extended the capabilities of this project by configuring it for Kubernetes (K8s) deployment. These changes include:

- **MongoDB Configuration**: I've made adjustments to the `backend/config.js` file to configure the MongoDB URL. This modification allows our backend to seamlessly interact with a MongoDB database deployed within our Kubernetes cluster.

- **Docker Image Optimization**: To ensure efficient image management, I've created Dockerfiles for both the backend and frontend components. These Dockerfiles are designed to use minimal base images, reducing image size and enhancing performance.

- **Development Environment Simplification**: A `docker-compose.yaml` file has been introduced to simplify the setup of the development environment. This Docker Compose file orchestrates the deployment of the application's components, streamlining development.

- **Kubernetes Manifests**: To further enhance the scalability and manageability of the project, I've added a series of Kubernetes manifests:

- `frontend.yaml`: This file contains definitions for the frontend service and deployment.
- `backend.yaml`: It includes configurations for the backend service and deployment.
- `database.yaml`: This manifest defines the MongoDB deployment and service.
- `database-secrets.yaml`: For enhanced security, MongoDB username and password are stored as secrets.
- `mongo-express.yaml`: This file contains deployment and service definitions for the Mongo Express admin interface.
- `mongo-express-secrets.yaml`: Safely stores MongoDB credentials and URL.
- `ingress.yaml`: By configuring this file, we enable access to our application via the domain book-store.com.

These updates are strategically aimed at improving the project's scalability and making it easier to deploy and manage within a Kubernetes environment.

## Future Improvements

Our project is an ongoing work in progress, with plans for further enhancements in the pipeline. Stay tuned for more updates and new features!
7 changes: 7 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:18.18-slim
WORKDIR /backend
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 5555
CMD ["npm", "run", "dev"]
9 changes: 5 additions & 4 deletions backend/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export const PORT = 5555;

export const mongoDBURL =
'mongodb+srv://root:[email protected]/books-collection?retryWrites=true&w=majority';
export const mongoDBURL = 'mongodb://root:[email protected]:27017/books-collection?authSource=admin';

// Please create a free database for yourself.
// This database will be deleted after tutorial

// FORMAT: mongodb://username:password@hosts/books-collection?authSource=admin';

// 'mongodb+srv://root:[email protected]/books-collection?retryWrites=true&w=majority';
54 changes: 54 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# ME_CONFIG_MONGODB_URL : mongodb://root:example@mongo:27017/books-collection # use database service name in place of mongo


version: '3.9'
services:
mongo:
image: mongo:7.0-jammy
container_name: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db

mongo-express:
image: mongo-express
container_name: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: example
ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/
depends_on:
- mongo

# Node.js (Express) service
express-app:
build:
context: ./backend
container_name: backend
ports:
- "5555:5555"
depends_on:
- mongo
- mongo-express
# environment:
# MONGO_URI: mongodb://root:[email protected]:27017/books-collection?authSource=admin

# Frontend service
react-app:
build:
context: ./frontend
container_name: frontend
ports:
- "80:80"
depends_on:
- express-app

volumes:
mongo-data:
11 changes: 11 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:18.18-slim as build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine3.18-slim
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
32 changes: 32 additions & 0 deletions kubernetes-manifests/1.frontend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: saurabhkr952/book-store-mern:frontend-fe665f5778ad45d93543cab0a7da2b814337e99f
ports:
- containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
51 changes: 51 additions & 0 deletions kubernetes-manifests/2.backend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: saurabhkr952/book-store-mern:backend-3e4c8acf07dd15709520d6f44aa7272c5e856bc7
ports:
- containerPort: 5555
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: backend-data
---
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: LoadBalancer
selector:
app: backend
ports:
- protocol: TCP
port: 5555
targetPort: 5555

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: backend-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
42 changes: 42 additions & 0 deletions kubernetes-manifests/3.database.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo:7.0-jammy
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secrets
key: MONGO_INITDB_ROOT_USERNAME # mongodb username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secrets
key: MONGO_INITDB_ROOT_PASSWORD # mongodb password
ports:
- containerPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: mongo
spec:
selector:
app: mongo
ports:
- protocol: TCP
port: 27017
targetPort: 27017
Loading

0 comments on commit 05d054d

Please sign in to comment.