Skip to content

Commit 2016ca8

Browse files
committed
deployed with CICD pipelines
1 parent ef4f2fd commit 2016ca8

12 files changed

Lines changed: 414 additions & 42 deletions

File tree

.github/workflows/ci.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
lint:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Check out code
16+
uses: actions/checkout@v3
17+
18+
- name: Set up Node.js
19+
uses: actions/setup-node@v3
20+
with:
21+
node-version: '20'
22+
23+
- name: Install frontend dependencies
24+
run: npm install
25+
working-directory: ./frontend
26+
27+
- name: Lint frontend
28+
run: npm run lint
29+
working-directory: ./frontend
30+
31+
build-and-push:
32+
runs-on: ubuntu-latest
33+
needs: lint
34+
steps:
35+
- name: Check out code
36+
uses: actions/checkout@v3
37+
38+
- name: Log in to Docker Hub
39+
uses: docker/login-action@v2
40+
with:
41+
username: ${{ secrets.DOCKERHUB_USER }}
42+
password: ${{ secrets.DOCKERHUB_PASS }}
43+
44+
- name: Build and push frontend image
45+
uses: docker/build-push-action@v4
46+
with:
47+
context: ./frontend
48+
file: ./frontend/Dockerfile.prod
49+
push: true
50+
tags: ${{ secrets.DOCKERHUB_USER }}/frontend:latest
51+
52+
- name: Build and push backend image
53+
uses: docker/build-push-action@v4
54+
with:
55+
context: ./backend
56+
file: ./backend/Dockerfile.prod
57+
push: true
58+
tags: ${{ secrets.DOCKERHUB_USER }}/backend:latest
59+
60+
- name: Build and push service image
61+
uses: docker/build-push-action@v4
62+
with:
63+
context: ./service
64+
file: ./service/Dockerfile.prod
65+
push: true
66+
tags: ${{ secrets.DOCKERHUB_USER }}/service:latest
67+
68+
deploy:
69+
runs-on: ubuntu-latest
70+
needs: build-and-push
71+
steps:
72+
- name: Check out code
73+
uses: actions/checkout@v3
74+
75+
- name: Build frontend
76+
run: npm install && npm run build
77+
working-directory: ./frontend
78+
79+
- name: Deploy Frontend to Netlify
80+
uses: nwtgck/actions-netlify@v2
81+
with:
82+
publish-dir: './frontend/dist'
83+
production-branch: main
84+
deploy-message: "Deploy from GitHub Actions"
85+
env:
86+
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
87+
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
88+
timeout-minutes: 1
89+
90+
- name: Deploy Backend to Render
91+
run: curl -X POST ${{ secrets.RENDER_BACKEND_DEPLOY_HOOK_URL }}
92+
93+
- name: Deploy Service to Render
94+
run: curl -X POST ${{ secrets.RENDER_SERVICE_DEPLOY_HOOK_URL }}

Jenkinsfile

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
pipeline {
2+
agent none
3+
4+
environment {
5+
DOCKERHUB_CREDENTIALS_ID = 'dockerhub-credentials'
6+
DOCKERHUB_USERNAME = 'your-dockerhub-username' // It is recommended to set this from Jenkins credentials
7+
}
8+
9+
stages {
10+
stage('Lint Frontend') {
11+
agent {
12+
docker {
13+
image 'node:20-slim'
14+
}
15+
}
16+
steps {
17+
dir('frontend') {
18+
sh 'npm install'
19+
sh 'npm run lint'
20+
}
21+
}
22+
}
23+
24+
stage('Build Images') {
25+
agent any
26+
steps {
27+
script {
28+
docker.build("${env.DOCKERHUB_USERNAME}/frontend:latest", "-f frontend/Dockerfile.prod frontend")
29+
docker.build("${env.DOCKERHUB_USERNAME}/backend:latest", "-f backend/Dockerfile.prod backend")
30+
docker.build("${env.DOCKERHUB_USERNAME}/service:latest", "-f service/Dockerfile.prod service")
31+
}
32+
}
33+
}
34+
35+
stage('Push Images to Docker Hub') {
36+
agent any
37+
steps {
38+
echo 'Pushing images to Docker Hub...'
39+
withCredentials([usernamePassword(credentialsId: env.DOCKERHUB_CREDENTIALS_ID, usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) {
40+
sh "docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}"
41+
sh "docker push ${env.DOCKERHUB_USERNAME}/frontend:latest"
42+
sh "docker push ${env.DOCKERHUB_USERNAME}/backend:latest"
43+
sh "docker push ${env.DOCKERHUB_USERNAME}/service:latest"
44+
}
45+
}
46+
}
47+
48+
stage('Deploy Frontend to Netlify') {
49+
agent {
50+
docker {
51+
image 'node:20-slim'
52+
}
53+
}
54+
steps {
55+
dir('frontend') {
56+
sh 'npm install'
57+
sh 'npm run build'
58+
// Assumes NETLIFY_AUTH_TOKEN and NETLIFY_SITE_ID are configured in Jenkins
59+
// sh 'npm install -g netlify-cli'
60+
// sh 'netlify deploy --prod --dir=dist'
61+
echo 'Deploying to Netlify...'
62+
}
63+
}
64+
}
65+
66+
stage('Deploy Backend to AWS Lambda') {
67+
agent any // Or an agent with AWS CLI and necessary tools
68+
steps {
69+
echo 'Deploying backend to AWS Lambda...'
70+
// This is a placeholder. A real deployment would be more complex.
71+
// You might use Serverless Framework, AWS SAM, or a custom script.
72+
// Example with a custom script:
73+
// dir('backend') {
74+
// sh './deploy-to-lambda.sh'
75+
// }
76+
}
77+
}
78+
79+
stage('Deploy Service') {
80+
agent any
81+
steps {
82+
echo 'Deploying the service...'
83+
// The service appears to be a background worker.
84+
// You could deploy this to a container service like AWS Fargate or a small VM.
85+
// Example for AWS Fargate:
86+
// sh 'aws ecs update-service --cluster your-cluster --service your-service --force-new-deployment'
87+
}
88+
}
89+
}
90+
}

backend/Dockerfile.dev

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Use an official Node.js runtime as a parent image
2+
FROM node:20-slim
3+
4+
# Set the working directory in the container
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json to the working directory
8+
COPY package*.json ./
9+
10+
# Install any needed packages
11+
RUN npm install
12+
13+
# Copy the rest of the application's code
14+
COPY . .
15+
16+
# Make port 5000 available to the world outside this container
17+
EXPOSE 5000
18+
19+
# Run the app when the container launches
20+
CMD ["npm", "run", "dev"]

backend/Dockerfile.prod

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Use an official Node.js runtime as a parent image
2+
FROM node:20-slim
3+
4+
# Set the working directory in the container
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json to the working directory
8+
COPY package*.json ./
9+
10+
# Install only production dependencies
11+
RUN npm install --omit=dev
12+
13+
# Copy the rest of the application's code
14+
COPY . .
15+
16+
# Make port 5000 available to the world outside this container
17+
EXPOSE 5000
18+
19+
# Run the app when the container launches
20+
CMD ["npm", "start"]

docker-compose.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
version: '3.8'
2+
3+
services:
4+
frontend:
5+
build:
6+
context: ./frontend
7+
dockerfile: Dockerfile.dev
8+
ports:
9+
- "5173:5173"
10+
volumes:
11+
- ./frontend:/app
12+
- /app/node_modules
13+
14+
backend:
15+
build:
16+
context: ./backend
17+
dockerfile: Dockerfile.dev
18+
ports:
19+
- "5000:5000"
20+
volumes:
21+
- ./backend:/app
22+
- /app/node_modules
23+
24+
service:
25+
build:
26+
context: ./service
27+
dockerfile: Dockerfile.dev
28+
ports:
29+
- "3000:3000"
30+
volumes:
31+
- ./service:/app
32+
- /app/node_modules

frontend/Dockerfile.dev

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Use an official Node.js runtime as a parent image
2+
FROM node:20-slim
3+
4+
# Set the working directory in the container
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json to the working directory
8+
COPY package*.json ./
9+
10+
# Install any needed packages
11+
RUN npm install
12+
13+
# Copy the rest of the application's code
14+
COPY . .
15+
16+
# Make port 5173 available to the world outside this container
17+
EXPOSE 5173
18+
19+
# Run the app when the container launches
20+
CMD ["npm", "run", "dev"]

frontend/Dockerfile.prod

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Build stage
2+
FROM node:20-slim as build
3+
4+
# Set the working directory
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json
8+
COPY package*.json ./
9+
10+
# Install dependencies
11+
RUN npm install
12+
13+
# Copy the rest of the application code
14+
COPY . .
15+
16+
# Build the project
17+
RUN npm run build
18+
19+
# Serve stage
20+
FROM nginx:stable-alpine
21+
22+
# Copy the build output to replace the default nginx contents.
23+
COPY --from=build /app/dist /usr/share/nginx/html
24+
25+
# Expose port 80
26+
EXPOSE 80
27+
28+
# Start nginx
29+
CMD ["nginx", "-g", "daemon off;"]

frontend/src/hooks/use-notifications.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect } from 'react';
1+
import { useState, useEffect, useCallback } from 'react';
22
import { Notification } from '@/components/ui/NotificationBell';
33

44
const useNotifications = () => {
@@ -11,7 +11,7 @@ const useNotifications = () => {
1111
}
1212
}, []);
1313

14-
const addNotification = (notification: Omit<Notification, 'id' | 'time'>) => {
14+
const addNotification = useCallback((notification: Omit<Notification, 'id' | 'time'>) => {
1515
const newNotification: Notification = {
1616
...notification,
1717
id: new Date().toISOString(),
@@ -22,7 +22,7 @@ const useNotifications = () => {
2222
localStorage.setItem('notifications', JSON.stringify(updatedNotifications));
2323
return updatedNotifications;
2424
});
25-
};
25+
}, []);
2626

2727
const clearNotification = (id: string | number) => {
2828
setNotifications((prev) => {

0 commit comments

Comments
 (0)