git clone <your-repo-url>
cd ReciFEEDThe components of this project can be run locally, but be aware that the current repo version utilizes the Kubernetes Deployment instructions (2) for the endpoints of interaction between components, so, in this setup case, connection URLs must be changed to function.
- Node.js (v14 or higher)
- npm or yarn
- MongoDB (local or cloud)
# Create and setup frontend
cd frontend
npm install
npm start# Setup monolith
cd monolith
npm install
npm start# Setup analytics service
cd services/analytics-service
npm install
npm start# Setup Bluesky service
cd services/bsky-service
npm install
npm start# Setup recipe query service
cd services/recipe-query-service
npm install
npm start# Setup Twitter service service
cd services/twitter-service
npm install
npm startThis project requires environment variables to connect to MongoDB and other external services.
# Monolith Port
PORT=5050
# MongoDB connection URI
MONGODB_URI=mongodb+srv://<username>:<password>@recifeed-cluster-0.yywkfdd.mongodb.net/recifeed_db?retryWrites=true&w=majority
# Token Generation Secret
JWT_SECRET=5e01f95b10e1688ad88a1ddd2d85f9fb7c8d8bb4ea977f507010b8682bd0604a7ae7f6481b648b898dfd612e83f9279d85b7911d2bb4fb07a6a7165a4e767932# Recipe query service port
PORT=3083
# Mistral AI Key for querying LLM models
MISTRAL_API_KEY=7QOauC1jWUCdIVZWstFclHuX058GwQIK# Twitter Service port
PORT=3084
# Twitter API Keys
TWITTER_CONSUMER_KEY=I7XuoARJzdlP1OZjqKqbnMscG
TWITTER_CONSUMER_SECRET=c6BMACuw7vQnXOQr0MrV5A0mHK1yl8hWJeXOlMPOh2TVI7qyPS
# MongoDB connection URI (recifeed_db)
MONGODB_URI=mongodb+srv://<username>:<password>@recifeed-cluster-0.yywkfdd.mongodb.net/recifeed_db?retryWrites=true&w=majority
# JWT Secret - MUST MATCH MONOLITH
JWT_SECRET=5e01f95b10e1688ad88a1ddd2d85f9fb7c8d8bb4ea977f507010b8682bd0604a7ae7f6481b648b898dfd612e83f9279d85b7911d2bb4fb07a6a7165a4e767932# Bsky Service port
PORT=3082
# MongoDB connection URI (recifeed_db)
MONGODB_URI=mongodb+srv://<username>:<password>@recifeed-cluster-0.yywkfdd.mongodb.net/recifeed_db?retryWrites=true&w=majority
# JWT Secret - MUST MATCH MONOLITH
JWT_SECRET=5e01f95b10e1688ad88a1ddd2d85f9fb7c8d8bb4ea977f507010b8682bd0604a7ae7f6481b648b898dfd612e83f9279d85b7911d2bb4fb07a6a7165a4e767932# Analytics Service port
PORT=3081
# MongoDB connection URI (recifeed_db)
MONGODB_URI=mongodb+srv://<username>:<password>@recifeed-cluster-0.yywkfdd.mongodb.net/recifeed_db?retryWrites=true&w=majority
# JWT Secret - MUST MATCH MONOLITH
JWT_SECRET=5e01f95b10e1688ad88a1ddd2d85f9fb7c8d8bb4ea977f507010b8682bd0604a7ae7f6481b648b898dfd612e83f9279d85b7911d2bb4fb07a6a7165a4e767932Running on Kubernetes can run the application with its current request paths, which are not local the process above generates.
analytics-service in this current project implementation is the only microservice deployed on the cloud, as seen in its external IP. Follow these steps to deploy the service to the cloud.
-
Follow the Google Kubernetes tutorial for deploying a Docker project to GKE, and replace all instances of the example
hello-appfrom the demo with our ReciFEED project, building the Docker image in themicroservices/analytics-servicefolder, until you reach the Deploy the hello-app to GKE step. -
Change the
imagename in/k8s/production/analytics-deployment.yamlto the docker image name built in this tutorial. -
Once you create the GKE cluster, to covers those settings to deploy the pods and start the service, instead of the remaining steps, run:
kubectl apply -f k8s/production- Create needed environment secrets for this deployment, using the same
.envvalues as the rest of the project for these two:
kubectl create secret generic analytics-secret \
--from-literal=MONGODB_URI=mongodb+srv://<username>:<password>@recifeed-cluster-0.yywkfdd.mongodb.net/recifeed_db?retryWrites=true&w=majority \
--from-literal=JWT_SECRET=<CRYPTOGRAPHIC_KEY>- Now when you should see
recipe-servicepods running when you run:
kubectl get pods- Now the external IP of this service should be available when you run:
kubectl get service- This is the IP being used in
frontend/src/services/analyticsService.jsto make calls to the analytics service. To use your IP, replace this one.
On your local terminal, build and deploy all others to minikube Kubernetes.
- Start minikube and set to Docker environment.
minikube start --driver=docker
eval $(minikube -p minikube docker-env)- Create secret keys from the above
.envin this environment.
kubectl create secret generic api-secret \
--from-literal=MONGODB_URI="mongodb+srv://<username>:<password>@recifeed-cluster-0.yywkfdd.mongodb.net/recifeed_db?retryWrites=true&w=majority" \
--from-literal=JWT_SECRET="<CRYPTOGRAPHIC_KEY>"
kubectl create secret generic recipe-query-secret \
--from-literal=MISTRAL_API_KEY="<KEY>"
kubectl create secret generic twitter-secret \
--from-literal=TWITTER_CONSUMER_KEY="<KEY>" \
--from-literal=TWITTER_CONSUMER_SECRET="<KEY>"- Build all Docker images
docker build -t monolith:latest ./ReciFEED/monolith
cd ./ReciFEED/microservices
docker build -t bsky-service:latest ./bsky-service
docker build -t recipe-query-service:latest ./recipe-query-service
docker build -t twitter-service:latest ./twitter-service- Install Ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml- Apply all config files to deploy and get services
kubectl apply -f k8s/local- Pods should be running when you run:
kubectl get pods- Get Ingress External IP and use as the host of all services
kubectl get ingress- Update local hosts file to run IP on
recifeed.example.com. Add to /etc/hosts:
<INGRESS-IP> assign4.example.com- Use
assign4.example.comas the base URL for all services in the frontend (current repo uses).
The project connects to the following external services.
- Mistral AI:: small LLMs called via HTTP, view linked documentation to setup account and receive above API keys.
- Twitter/X: authenticate with a Twitter user and gain control over actions, view linked documentation to gain both above developer keys.
- Bluesky: authenticate with a Bsky user and gain control over actions, view linked documentation to view API usage tutorials.
To run documentation for this API, run the following commands:
cd ./api-docs/monolith
npm install
npm startThe monolith documentation will run on http://localhost:2020.
In another terminal:
cd ./api-docs/monolith
npm install
npm startThe microservice documentation will run on http://localhost:2021.
The analytics dashboard is available on the frontend at the route http://localhost:3000/analytics. It currently contains the following metrics for this application:
- Current Active Users (unique users which have logged a meaningful interaction within the last minutes)
- Live Post Interactions (number of comments and likes within the last 3 seconds)
- Live Recipe Views (number within the last 3 seconds)
- Most Popular User Pages (within the last 1d, 1w, 1m)
- Most Popular Recipe Pages (within the last 1d, 1w, 1m)
- Most Popular Search Terms (within the last 1d, 1w, 1m)
Common Errors
- Kubernetes Deployment: Ensure kubetcl environment is set to build in Docker. If they appear locally, they are wrong.
- Minikube Memory Error: Current fix, create a new profile in Minikube and start commands there.
TCSS559-RECIFEED/
├─ monolith/
│ ├─ controllers/
│ │ ├─ postController.js
│ │ ├─ recipeController.js
│ │ ├─ searchController.js
│ │ └─ userController.js
│ ├─ database/
│ │ ├─ initialization/
│ │ │ ├─ createIndexes.js
│ │ │ └─ importExampleData.js
│ │ └─ connection.js
│ ├─ models/
│ │ ├─ post.js
│ │ ├─ recipe.js
│ │ ├─ search.js
│ │ └─ user.js
│ ├─ routes/
│ │ ├─ postRoutes.js
│ │ ├─ recipeRoutes.js
│ │ ├─ searchRoutes.js
│ │ └─ userRoutes.js
│ ├─ utils/ # helpers (e.g., errorHandler.js)
│ ├─ .env # NOT committed - use provided
│ └─ server.js # Express app entry
│
├─ microservices/
│ ├─ analytics-service/
| | ├─ database/
│ | │ └─ connection.js
| | ├─ models/
│ | │ └─ event.js
| | ├─ routes/
| | | |─ eventRoutes.js
| | | |─ popularRoutes.js
│ | │ └─ liveRoutes.js
| | |─ .env # NOT committed - use provided
│ │ └─ index.js
│ ├─ recipe-query-service/
| | |─ .env # NOT committed - use provided
│ │ └─ index.js
│ ├─ twitter-service/
| | ├─ database/
│ | │ └─ connection.js
| | ├─ models/
│ | │ └─ twitterUserTokens.js
| | ├─ routes/
| | | |─ post.js
│ | │ └─ auth.js
| | |─ .env # NOT committed - use provided
│ │ └─ index.js
│ └─ bsky-service/
| ├─ database/
│ │ └─ connection.js
| ├─ models/
│ │ └─ bskyUserToken.js
| |─ .env # NOT committed - use provided
│ └─ index.js
│
└─ frontend/
├─ public/
└─ src/
├─ assets/ # icons & logos
├─ components/
│ ├─ Feed.css
│ ├─ Home.css
│ ├─ Login.css
│ ├─ Recipe.css
│ └─ Register.css
├─ layout/
│ ├─ Navbar.css
│ ├─ Navbar.js
│ ├─ Side_Bar.css
│ └─ Side_Bar.js
└─ pages/
├─ Feed.js
├─ Home.js
├─ Login.js
├─ Recipe.js
└─ Register.js
- Frontend: React.js, Axios, React Router
- Backend: Node.js, Express.js, MongoDB, JWT
- Authentication: JWT tokens
- Image Upload: Multer
- Celestine Buendia
- Sopheanith Ny
MIT