This application integrates multiple services: a React frontend, a Node.js backend, a Redis message broker, and a PostgreSQL database. The following describes the system components and their interaction:
-
Frontend (React - client):
The React application serves as the user interface, collecting input from users and sending requests to the backend server. The frontend interacts with the backend via HTTP requests. -
Backend (Node.js - server):
The Node.js server handles HTTP requests from the frontend. It performs business logic, processes user input, publishes tasks to the Redis message queue, and stores the user input in the PostgreSQL database. -
Worker Service:
The worker service subscribes to Redis channel forinsertevent. Wheninsertevent is published to the Redis channel, the worker retrieves it, performs the required computation (e.g., calculates Fibonacci numbers), and stores the result in Redis as a key-value pair. The PostgreSQL database only stores the user input (the number), while Redis stores both the user input and the computed result. -
Nginx Reverse Proxy:
Nginx serves as a reverse proxy that routes traffic to either the frontend (React) or the backend (Node.js) based on the URL. It ensures traffic distribution. -
Redis (Pub/Sub):
Redis is used as a message broker between the backend and the worker service. The backend publishesinsertevent (e.g., Fibonacci calculation) to Redis channel. The worker subscribes forinsertevent and performs computations. Redis also stores the key-value pairs for user input numbers and computed Fibonacci results. -
PostgreSQL Database:
The database stores the user input (number) for persistence. Only the user input is saved in the database, while Redis holds both the input and the computed Fibonacci results for real-time access.
-
User Interaction:
A user inputs a number in the React frontend (client), which sends a request to the Node.js backend to calculate the Fibonacci number for the given input. -
Backend Processing:
- The backend (Node.js) stores the user input in the PostgreSQL database for persistence.
- The backend then publishes the input (number) to a Redis channel using the Redis publisher. This action notifies the worker service to process the task.
-
Task Processing by Worker:
- The worker service subscribes to the Redis channel.
- When the worker service receives
insertevent (user input), it computes the Fibonacci result asynchronously. - The Fibonacci result is saved in Redis as a key-value pair, where the key is the user input (number) and the value is the calculated Fibonacci result.
- The PostgreSQL database only stores the user input (the number), without the computed result.
-
Real-time Data Access:
- Users can query all stored input values from the PostgreSQL database via the backend (accessible through the
/values/allroute). - For real-time updates, users can query Redis to get the current Fibonacci results, as stored in Redis under the
/values/currentroute.
- Users can query all stored input values from the PostgreSQL database via the backend (accessible through the
- Frontend: React (client-side)
- Backend: Node.js (server-side), Express
- Worker: Node.js (worker), Redis Pub/Sub for event messaging
- Database: PostgreSQL (for data persistence)
- Message Broker: Redis (used for pub/sub and caching)
- Reverse Proxy: Nginx (routes traffic to the correct service)
- Deployment: AWS Elastic Beanstalk for deployment of Docker containers
-
Docker:
All services (frontend, backend, worker, Nginx) are containerized using Docker. This ensures that each service runs in its own isolated environment, making the application scalable and easy to manage. -
Docker Compose:
Docker Compose is used to define and manage the multi-container environment for development and deployment. It ensures that the services can interact seamlessly with one another. -
Elastic Beanstalk:
AWS Elastic Beanstalk is used to deploy the multi-container Docker application. It automates the deployment process, including scaling, load balancing, and monitoring of the application.
This project deploys a multi-container Docker application to AWS Elastic Beanstalk using GitHub Actions. Each service runs inside its own Docker container.
-
Push Docker Images to Docker Hub:
Docker images are built for each service (client, server, worker, Nginx) and pushed to Docker Hub. -
Prepare Docker Environment:
Docker Compose is used to define and configure the multi-container environment. -
Deploy with AWS Elastic Beanstalk:
The application is deployed to AWS Elastic Beanstalk using Docker. Elastic Beanstalk manages the infrastructure, scaling, and networking. -
Monitor & Scale:
Elastic Beanstalk automatically scales the application based on demand and ensures the proper routing of requests to services.
- Push code to GitHub
mainbranch. - GitHub Actions automatically:
- Builds images for client, server, worker, nginx.
- Pushes images to Docker Hub.
- Creates
deploy.zip(zipping all project files [excluding.git]). - Deploys
deploy.zipto Elastic Beanstalk.
- Elastic Beanstalk:
- Reads
docker-compose.yml. - Pulls images from Docker Hub.
- Runs the app.
- Reads
In your GitHub repository, go to Settings > Secrets and variables > Actions, add these secrets:
| Secret Name | Description |
|---|---|
| DOCKER_USERNAME | Your Docker Hub username |
| DOCKER_PASSWORD | Your Docker Hub password |
| AWS_ACCESS_KEY | AWS IAM user access key |
| AWS_SECRET_ACCESS_KEY | AWS IAM user secret access key |
/client--> React frontend/server--> Node.js backend/worker--> Worker service/nginx--> Nginx reverse proxydocker-compose.yml--> Tells AWS how to run everything together
✅ You must zip everything (all folders and files: client/, server/, worker/, nginx/, docker-compose.yml, etc).
✅ Do NOT zip only Dockerrun.aws.json or docker-compose.yml alone.
✅ docker-compose.yml must be inside the zip at the root level (not hidden in a folder).
Correct way to zip:
zip -r deploy.zip . -x '*.git*'