PeerPrep is a platform on which users are able to prepare for technical interviews by matching with peers and practicing interview questions in a collaborative space.
The cloud deployment of PeerPrep is available at https://peerprep.yuanzheng.pro.
PeerPrep was developed as part of AY23/24S1 CS3219 Software Engineering Principles and Patterns by Group 40 (Chia Yu Hong, Chinthakayala Jyothika Siva Sai, Justin Widodo, Tan Yuan Zheng, Xu Richard Chengji)
The main structure of the repository consists of three sub-directories, /frontend
, /api-gateway
, and /backend
.
Additionally, Github Actions workflows for configuring the CI/CD pipeline are located under the /.github/workflows
directory and the /gke
directory contains the .yaml
files for deploying on the Google Kubernetes Engine (GKE). Also located in the project root are the function.js
file that defines the serverless function, and the docker-compose.yml
file for local deployment.
The /frontend
sub-directory contains files relevant to the Angular frontend. This sub-directory has most of its config files under /frontend/src
, while the rest of the files are under the /frontend/src/app
directory. These files are organised as follows:
/_guards
: authentication and role guards on routes/_helpers
: HTTP request interceptor helper/_services
:___.service.ts
files for handling different services/<component>
: containing the___.component.css
,___.component.html
,___.component.spec.ts
,___.component.ts
files for each componentapp
files that define the "root" of the Angular frontend
The /api-gateway
sub-directory contains files relevant to the API gateway, implemented with NGINX. It contains the .conf
files necessary for configuring the API Gateway, as well as the Dockerfile
for building the image of the API Gateway.
The /backend
sub-directory contains files relevant to the microservices that make up the backend of PeerPrep. Each /backend/___-service
directory is generally structured as follows:
/config
: the relevant config files, such asdb.config.js
/controllers
: the___.controller.js
files defining the methods used by the microservice/models
: relevant files defining the models used by the microservice/routes
:___.routes.js
files defining the routes exposed by the microserviceDockerfile
: defines how the image of the microservice is builtindex.js
: handles startup and configuration of the microservice with the relevant files
The structure of each microservice may differ from this general structure in the case that some parts are not relevant to the function of the microservice.
The /gke
directory contains sub-directories for deploying the API gateway and each of the microservices on the Google Kubernetes Engine (GKE). Each sub-directory contains ___-deployment.yaml
and ___.service.yaml
files for deploying a Deployment and Service respectively. The API gateway additionally has an api-gateway-ingress.yaml
file for configuring an ingress for routing external traffic into the API gateway.
PeerPrep supports both local deployment with Docker Compose, for development and testing purposes, and cloud deployment with Vercel (Frontend) and Google Kubernetes Engine (GKE) (API Gateway + Microservices).
- Install Docker Desktop
- Configure the
JWT_SECRET
for use in local deployment in/backend/user-service/config/auth.config.js
if desired. The default value used is"the-inner-machinations-of-my-mind-are-an-enigma"
To run the project:
- Ensure a Docker daemon is running
cd
to the root of the project- In a terminal run:
docker-compose up
, or,docker-compose up -d
to run in detached mode
The locally deployed PeerPrep may be accessed in a web browser at the URL 127.0.0.1:8000
.
To tear down the project:
- In a terminal, run:
docker-compose down
To elevate a user to an admin
role:
- Execute the following commands in the integrated terminal of the running
user-db
container (On Docker Desktop, go to "Containers" > "user-db
" > "Exec"):mongosh
use user_db
var adminid = db.roles.findOne({name:'admin'}, {_id:1})._id
db.users.updateOne({ username: '<CREATED_USERNAME>' }, { $set: { roles: [adminid] } })
(where <CREATED_USERNAME>
is the username of an existing user to be elevated to an admin
role)
- Set up a Google Cloud project
- Set up a cluster in the project
- Set up a repository in the Artifact Registry
- Set up a service account with sufficient permissions
- For reference, PeerPrep uses a service account with the following roles:
- Artifact Registry Reader
- Artifact Registry Repository Administrator
- Artifact Registry Service Agent
- Artifact Registry Writer
- Editor
- Kubernetes Engine Service Agent
- Security Reviewer
- Service Account Token Creator
- Service Usage Admin
- For reference, PeerPrep uses a service account with the following roles:
- Generate a service account key for the service account
- Configure the following GitHub repository secrets ("Settings" > "Security" > "Secrets and variables" > "Actions"):
GKE_PROJECT
: the ID of the Google Cloud Project set upGKE_SA_KEY
: the generated service account key for the service account with sufficient permissions
- Set up MongoDB Atlas account
- Under "Secrets & ConfigMaps" on GKE, configure the following for the created cluster:
- A
db-admin
secret withdb-username
anddb-password
matching the username and password of the created MongoDB Atlas account - An
db-admin
secret withjwt-secret
set to the desired secret for cloud deployment
- A
- Provision TLS certification for the domain name used by the backend
- Reserve a global static IP on Google Cloud
- Configure
./frontend/src/environments/environment.ts
with the certified domain name<BACKEND_DOMAIN_NAME>
as follows:BACKEND_API: <BACKEND_DOMAIN_NAME>
Frontend Cloud Deployment:
- Log in/Sign up for Vercel, and add a new project from the homepage.
- Under “Import Git Repository”, press “Import” on your GitHub repository containing the project. If the repository is not listed as an option, you can add it by clicking on “Adjust GitHub App Permissions →”.
- At the “Configure Project” page, give the project a name. Choose “Angular”, and select
./frontend
as the root directory. - Click deploy. Vercel will now build the deployment and update it whenever a change is pushed to the repository.
Backend Cloud Deployment:
The instructions for configuring the deployment of the API gateway and the microservices to Google Kubernetes Engine (GKE) are as follows:
- In each
deploy-___.yml
file of the/.github/workflows
directory, configure each of theGKE_CLUTER
,GKE_ZONE
,REPOSITORY_NAME
as per the setup in "Requirements" - Configure the
image
in each of the.yaml
files under./gke
to point to the appropriate image in the repository on the Artifact Registry - Configure the
global-static-ip-name
annotation inapi-gateway-ingress.yaml
to point to the global static IP reserved - Manually trigger the deployment workflows for each component under "Actions", or have them automatically trigger on changes to the relevant files
Serverless Function Deployment:
The serverless function is automatically deployed to the Google Cloud Platform on a push to the master
branch. The instructions to manually deploy the serverless function are as follows:
- Ensure that
gcloud
is installed. Run the following command in terminal:npm i gcloud
- Log in to Google Cloud Platform. Run the following command in terminal:
gcloud auth login
- Login using your Google Cloud Platform account
- Next, `cd`` into the function directory:
cd question-fetcher
- Deploy the application using the following command:
gcloud app deploy