Skip to content

Commit 15f6266

Browse files
authored
Merge pull request #66 from UTSC-CSCC01-Software-Engineering-I/feat/deployment
Feat/deployment
2 parents fffd746 + 5a8c2db commit 15f6266

25 files changed

Lines changed: 2423 additions & 184 deletions

.github/deploy-docker.yml

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Deploy App and Test
2+
on:
3+
workflow_run:
4+
workflows: ["Publish Project Backend to Dockerhub", "Publish Project Frontend to Dockerhub"]
5+
types:
6+
- completed
7+
workflow_dispatch:
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
timeout-minutes: 30
12+
env:
13+
GIT_TAG: ${{ github.ref_name }}
14+
steps:
15+
- name: SSH into VM and deploy
16+
uses: appleboy/ssh-action@v1
17+
with:
18+
host: "15.222.16.78"
19+
username: ubuntu
20+
key: ${{ secrets.KEY }}
21+
port: 22
22+
envs: GIT_TAG
23+
script: |
24+
cd epiready
25+
git fetch --tags
26+
TAG_NO_V=${GIT_TAG#v}
27+
export TAG_NO_V
28+
echo "Deploying version: $TAG_NO_V"
29+
git checkout $GIT_TAG || true
30+
docker compose pull
31+
docker compose up -d
32+
echo "Running Cypress tests in Cypress container..."
33+
docker compose run --rm cypress
34+
echo "Running performance test on deployed website..."
35+
sudo apt-get update && sudo apt-get install -y apache2-utils
36+
ab -n 100 -c 10 https://epiready.taggit.tech/

CICD/A2 CI-CD.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# 🧱 CI/CD System Design Document
2+
3+
**Project**: **Epiready**
4+
**Date**: 2025-07-28
5+
**Target Environment**: AWS Lightsail Ubuntu 24.04
6+
**Version**: 1.0
7+
8+
9+
---
10+
11+
## 1. 🔍 Overview
12+
13+
The CI/CD pipeline roughly performs 6 major steps:
14+
15+
* Uses NGINX as reverse proxy to serve website through HTTPS
16+
* Uses PostgreSQL container with named volume to keep data stored in the VM
17+
* Uses docker compose to run the docker containers in an isolated environment
18+
* Uses GitHub Actions for CI/CD automation(tests, building images, deployment)
19+
* Image hosting on DockerHub
20+
* Post-deployment E2E testing with Cypress
21+
22+
23+
---
24+
25+
## 2. Services Used
26+
27+
* **Web Hosting:** AWS Lightsail
28+
* **SSL Cetificate**: Let's Encrypt, Certbot(for renewing and getting SSL certificate from Let's Encrypt)
29+
* **Storing Images**: Dockerhub
30+
* **Reverse Proxy**: NGINX
31+
* **Database**: PostgreSQL
32+
* **e2e Testing**: Cypress
33+
* **CI/CD Automation**: Github Actions
34+
* **Performance Testing**: ApacheBench
35+
* **Container Management**: Docker compose
36+
37+
38+
---
39+
40+
## 3. 🧹 Components
41+
42+
### 3.1 Frontend
43+
44+
* Built using vite build through Dockerfile and pulled from Dockerhub
45+
* Serves static assets via NGINX
46+
* Communicates with backend over HTTPS
47+
48+
### 3.2 Backend
49+
50+
* Exposes RESTful API (HTTPS only)
51+
* Connects to PostgreSQL database
52+
* Secured via environment variables and CORS policies
53+
54+
**Dependecies:** PostgreSQL
55+
56+
### 3.3 Database
57+
58+
* PostgreSQL 14 (Docker)
59+
* Persistent volume for no data loss between deployments
60+
61+
### 3.4 NGINX
62+
63+
* Acts as reverse proxy
64+
* Handles HTTPS using Let's Encrypt or self-managed certs
65+
66+
**Dependencies:** Frontend, Backend
67+
68+
69+
---
70+
71+
## 4. 🔒 Security
72+
73+
* All secrets (SSH key, DockerHub credentials) stored in GitHub Secrets
74+
* HTTPS enforced via NGINX with certbot and Let's Encrypt
75+
* CSRF & CORS handled by backend
76+
* No direct ports exposed
77+
* All the keys for backend are stored in the epiready-backend/.env file in the vm for adding multiple keys easily
78+
* Using Github Secrets for injecting the frontend secrets at build time
79+
80+
81+
---
82+
83+
## 5. 🧚️‍♂️ Testing Strategy
84+
85+
All the tests are run via Github Actions, post-deployment tests are run after ssh-ing into the vm and then running tests.
86+
87+
* **Lint Tests**: Checks basic syntax using a linter to ensure the website doesn't have any breaking issues.
88+
* **Unit Tests**: Using Jest for frontend and Pytest for backend and running the tests on Pull Requests and Push to make sure no uncaught bugs are pushed into prod.
89+
* **End-to-End Tests**: End to end tests done via Cypress after the website is deployed to test functionality.
90+
* **Performance Tests**: Runs ApacheBench to do a basic load testing to test responsiveness of the website.
91+
92+
93+
---
94+
95+
## 6. 🚀 Architecture Diagram
96+
97+
<img width="530" height="420" alt="image" src="https://github.com/user-attachments/assets/3aeab0e5-1e6f-447d-a311-300f10e4b4f9" />
98+
99+
100+
---
101+
102+
## 7. Deployment Strategy
103+
104+
Using Recreate deployment pattern for deployment giving around 10 seconds of downtime per release. Recreate Deployment is used for cost and performance efficiency as two containers deplete the resources of the VM.
105+
106+
107+
---
108+
109+
## 8. Performance
110+
111+
Serving static files for more responsive frontend and doing basic performance testing, the deployment is able to handle 100 concurrent requests within 75 ms.
112+
113+
114+
---
115+
116+
## 9. 📌 Future Improvements
117+
118+
* Adding more containers and load balancer for horizontal scaling
119+
* Add alerting with Slack/email on deploy failure
120+
* Blue-green deployment for lower downtime
121+
* DB backup container & monitoring tools
122+
123+
124+
---
125+
126+

CICD/Backend-Dockerfile

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Stage 1: Build the React application
2+
FROM node:20-alpine AS builder
3+
4+
# Set the working directory
5+
WORKDIR /app
6+
7+
# Copy package.json and package-lock.json (or yarn.lock)
8+
COPY package*.json ./
9+
10+
11+
ARG VITE_BACKEND_URL
12+
ENV VITE_BACKEND_URL=$VITE_BACKEND_URL
13+
14+
ARG VITE_MAPS_KEY
15+
ENV VITE_MAPS_KEY=$VITE_MAPS_KEY
16+
17+
18+
# Install dependencies
19+
RUN npm install
20+
21+
# Copy the rest of the application source code
22+
COPY . .
23+
24+
# Build the application for production
25+
RUN npm run build
26+
27+
# Stage 2: Serve the application using a production-ready web server
28+
FROM nginx:stable-alpine
29+
30+
# Copy the built files from the builder stage
31+
COPY --from=builder /app/dist /usr/share/nginx/html
32+
33+
# Expose port 80 to the outside world
34+
EXPOSE 80
35+
36+
# Nginx will start automatically when the container starts
37+
CMD ["nginx", "-g", "daemon off;"]

CICD/Explaination.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# 🚀 Deployment Process Documentation
2+
3+
This document outlines the CI/CD deployment pipeline for the application, including how testing, Docker image management, deployment to the virtual machine (VM), and post-deployment checks are handled.
4+
5+
---
6+
7+
## 📦 Pre-Deployment Steps (CI)
8+
9+
### 1. **Linting and Unit Tests**
10+
11+
All code changes undergo automated testing using GitHub Actions:
12+
13+
### **Frontend**
14+
---
15+
16+
**Filename**: lint.yml
17+
18+
* **Linter:** Runs using ESLint.
19+
* **Unit Tests:** Run using **Jest**.
20+
21+
### **Backend**
22+
---
23+
24+
**Filename**: backend-lint.yml
25+
26+
* **Linter:** Runs using flake8
27+
* **Unit Tests:** Run using **pytest**.
28+
29+
### 2. **Build and Push Docker Images**
30+
31+
Triggered only when a Git **tag is pushed** (e.g., `v1.0.0`).
32+
33+
* **Frontend Image:**
34+
35+
* Dockerfile in `epiready-frontend/`
36+
* Built and tagged as `epiready-frontend:<git-tag>`
37+
38+
* **Backend Image:**
39+
40+
* Dockerfile in `epiready-backend/`
41+
* Built and tagged as `epiready-backend:<git-tag>`
42+
43+
* **Push:** Images are pushed to DockerHub using GitHub Actions.
44+
45+
---
46+
47+
## ☁️ Deployment to VM (CD)
48+
49+
### **Triggering Deployment Workflow**
50+
51+
A **workflow file** (`deploy-docker.yml`) is triggered **after build-backend.yml and build-frontend.yml are run succesfully.** This only runs when the other workflow files are run in the main branch, not before it.
52+
53+
### 1. **SSH Into VM**
54+
55+
* The workflow file then uses appleboy/ssh-action@v1 to ssh into the Lightsail VM and then goes to the epiready directory where it uses git pull to update the docker-compose file in case any new containers or modifications were made.
56+
57+
### 2. **Pull Docker Images**
58+
59+
* Uses Docker to pull:
60+
61+
* `your-dockerhub/frontend:<git-tag>`
62+
* `your-dockerhub/backend:<git-tag>`
63+
64+
### 3. **Deploy Using Docker Compose**
65+
66+
* Uses a `docker-compose.yml` file that defines:
67+
68+
* **Frontend container** (served via **NGINX**) with **Certbot** for HTTPS
69+
* **Backend container**
70+
* **PostgreSQL** service with a **named volume** for persistent storage
71+
72+
* Executes: `docker compose pull && docker compose up -d`
73+
74+
---
75+
76+
## 🔍 Post-Deployment Testing
77+
78+
### 7. **E2E Testing with Cypress**
79+
80+
* Cypress tests are triggered **after deployment completes**.
81+
* Run against the live application to simulate real-user flows.
82+
83+
### 8. **Load Testing with Apache Bench (ab)**
84+
85+
* Conducted to verify server performance and concurrency handling.
86+
* Example: `ab -n 100 -c 10 https://epiready.taggit.tech/`
87+
88+
89+
90+
## 🗂️ Versioning
91+
92+
* **Git Tags** (e.g., `v1.0.1`) determine image versions.
93+
* Helps maintain rollback strategy and historical traceability.
94+
95+
---
96+
97+
## 🔐 Secrets and Security
98+
99+
* SSH keys and DockerHub credentials are stored securely in **GitHub Secrets**.
100+
* Certbot is used to auto-renew SSL certificates for production.
101+
102+
103+
104+
## 📁 Folder Structure (Simplified)
105+
106+
```
107+
epiready/
108+
├── backend/
109+
│ └── Dockerfile
110+
├── frontend/
111+
│ └── Dockerfile
112+
├── docker-compose.yml
113+
├── .github/
114+
│ ├── workflows/
115+
│ │ ├── backend-lint.yml (backend tests)
116+
│ │ └── lint.yml (frontend tests)
117+
│ │ └── docker-deploy.yml (ssh + pull + deploy + post-tests)
118+
│ │ └── build-backend.yml (build and push backend)
119+
│ │ └── build-frontend.yml (build and push frontend)
120+
```
121+
122+
---
123+
124+
## ✅ Summary Checklist
125+
126+
[x] Run lint and unit tests
127+
[x] Build & push tagged Docker images
128+
[x] SSH into VM and deploy with docker-compose
129+
[x] Serve with NGINX + Certbot
130+
[x] PostgreSQL with volume
131+
[x] Run Cypress tests
132+
[x] Run Apache Bench
133+
134+
---
135+
136+
## 🔄 Future Enhancements (Optional)
137+
138+
* Add rollback automation on test failure
139+
* Add Slack/Discord notifications post-deploy
140+
* Enable blue-green deployments for zero downtime

0 commit comments

Comments
 (0)