ScholarScope - A Multi-Container Scholarship Search Portal

 ScholarScope - A Multi-Container Scholarship Search Portal

Name: V Padmasree

Reg No: 23BCE1797


Introduction

This report documents the comprehensive three-part process of designing, developing, and containerizing "ScholarScope," a full-stack web application designed to help students search and filter scholarships. The project's lifecycle was intentionally structured to demonstrate the progression from foundational tiers to a robust, production-ready, containerized system.

DA1 focused on establishing the Data Tier (PostgreSQL) and the Application Tier (Flask API), creating the core foundation for data storage and logic.

DA2 integrated the Presentation Tier (React Frontend), enabling communication between the user interface and the backend API.

DA3 achieved full containerization and deployment using Docker Compose and an Nginx Reverse Proxy, encapsulating all four services (DB, Backend, Frontend, Nginx) into isolated environments to demonstrate modern deployment best practices.


Objectives

Objectives of Part1 – DA1: Database and Backend Foundation

1. Data Schema Setup: Design and implement the PostgreSQL database schema for the scholarships table using the db/init.sql script.

2. Backend API Development: Build the Python/Flask REST API (app.py) to handle scholarship filtering and retrieval.

3. Containerization & Dependency: Define and containerize the scholarscope-db (PostgreSQL) and scholarscope-backend (Flask) services, ensuring the backend waits for the database to be healthy.

Objectives of Part2 – DA2: Frontend Development and Integration

1. Frontend Design: Develop the React user interface, including the search form (SearchForm.jsx) and results table (ScholarshipTable.jsx).

2. API Communication: Implement asynchronous data fetching (axios) to call the /api/scholarships endpoint.

3. Frontend Containerization: Create a multi-stage Dockerfile for the frontend, using Node.js for the build stage and Nginx for serving static content.

Objectives of Part3 – DA3: Final Orchestration and Reverse Proxy

1. Gateway Implementation: Define the scholarscope-nginx service to act as the single entry point and reverse proxy for the application.

2. Traffic Routing: Configure the Nginx proxy to correctly route root requests (/) to the frontend and API requests (/api/) to the backend.

3. Production Readiness: Ensure data persistence using a named volume (scholarscope_pg_data) and implement restart: always for critical services.

4. Deployment: Orchestrate the entire four-container stack using docker-compose up for the final demonstration.


Name of the Containers involved and the download links


Custom-Built Images

1. scholarscope-backend

(Flask-based API container, built from python:3.10-slim)

https://hub.docker.com/r/sree2105/scholarscope-backend


2. scholarscope-frontend

(React UI container, built from a multi-stage process ending in nginx:alpine)

https://hub.docker.com/r/sree2105/scholarscope-frontend


Official Docker Hub Images

scholarscope-db - PostgreSQL container for data persistence

scholarscope-nginx - Reverse proxy & load balancer container


Containers:

 



Name of the other software involved along with the purpose





Overall architecture of all three DAs

DA1 Architecture (DB & Backend Foundation)

Type: Two-tier logical architecture (before containerization).

Flow: Python (Flask) Application connects directly to PostgreSQL Database.

Persistence: Local PostgreSQL database layer.

Input: HTTP Requests (simulated for testing).

Output: JSON data of scholarships.


 


DA2 Architecture (Frontend Integration)

Type: Classic Three-Tier Architecture.

Flow: React Frontend (UI) makes Axios API calls → Flask Backend (Logic) executes database queries → PostgreSQL (Data) returns results.

Persistence: Centralized and permanent data layer in PostgreSQL.

Input: User interaction on the web form.

Output: Display of filtered scholarships on the UI.



 

DA3 Architecture (Final Containerized Application)

Type: Fully Containerized, Four-Service Micro-architecture.

Services: scholarscope-nginx (Gateway), scholarscope-frontend (UI), scholarscope-backend (API), scholarscope-db (Data).

Network: Single, isolated Docker bridge network (default to Docker Compose).

Input: HTTP requests via host port 80.

Output: Complete, self-contained multi-container web app accessible via a single URL.


 



description about the architecture 


Part 1: Architectural Philosophy and Core Components

The final architecture of the ScholarScope project represents a modern, multi-container application orchestrated by Docker Compose. This design separates the application's logic into four independent, isolated, and containerized services, a key principle of microservices architecture that enhances development speed, portability, and scalability.

The system is comprised of four distinct services, each with a single, clearly defined responsibility:

1. The Reverse Proxy Service (scholarscope-nginx): This container runs the Nginx web server. It serves as the single point of entry for all external traffic, listening on port 80 of the host machine. It intelligently routes requests: default paths (/) go to the frontend, while API calls (/api/) are proxied to the backend.

2. The Frontend Service (scholarscope-frontend): This container runs a lightweight NGINX server that serves the static React application files (HTML, CSS, and JavaScript). By using a multi-stage Docker build, the final image is highly optimized and only contains the compiled assets and the Nginx server.

3. The Backend Service (scholarscope-backend): This container runs the Python/Flask application, which is the core logic engine. It exposes a REST API (/scholarships) that performs complex SQL queries using parameters like CGPA, income limit, state, and gender to fetch filtered data from the database.

4. The Database Service (scholarscope-db): This container runs the PostgreSQL database engine. It's the application's persistent memory, storing the entire scholarships table, and is configured to be reliable and secure. It is initialized using the db/init.sql script upon first run.

All four services are defined and managed by a single, central file: docker-compose.yml.


Part 2: The Connective Tissues: Networking and Data Management

The true power of this architecture lies not just in the services themselves, but in how they are connected and how they manage data.

The Networking Layer:

The containers are automatically connected to a private virtual network created by Docker Compose, enabling seamless and secure internal communication:

Service Discovery: The backend (Flask) container does not use an IP address to find the database. Instead, it connects using the service name defined in docker-compose.yml, which is scholarscope-db. Docker's internal DNS resolves this name to the correct container, making the configuration highly portable.

Port Mapping: Only the Nginx container's port is explicitly mapped to the host, ensuring security and simplicity:

o Host Port 80 → scholarscope-nginx Container Port 80.

o The backend (port 8000) and database (port 5432) ports are not mapped to the host, making them completely inaccessible from the outside world for enhanced security.

The Data Management Layer (Volumes):

Named Volumes (for Persistence): The database service uses a named volume, scholarscope_pg_data. This volume stores the PostgreSQL data permanently on the host machine. This is critical for ensuring that all scholarship data persists even if the database container is stopped, removed, or updated.

Bind Mounts (for Development): During the development phase, bind mounts are used to map local source code directories (./backend, ./frontend) into the respective running containers. This enables a rapid development workflow where code changes on the host are instantly reflected inside the container without needing a full image rebuild.

Production-Readiness Features:

Health Check: The scholarscope-db service defines a healthcheck. This allows Docker to determine not only if the container is running, but if PostgreSQL is fully initialized and ready to accept connections before allowing the backend to start, thus preventing connection failures.

Restart Policy: The restart: always policy is applied to all critical services. This ensures that if any container fails or crashes, Docker will automatically restart it, providing high availability for the application.


Procedure

Procedure - Part1 - DA1: Backend and Database Setup

Project Setup: Created the backend/ and db/ directories.

Database Schema: Created db/init.sql with the scholarships table schema and seed data.

Backend Logic: Wrote backend/app.py, defining the Flask application and the query_scholarships function with dynamic SQL filter logic.

Container Definition: Defined the scholarscope-db and scholarscope-backend services in docker-compose.yml, including the DB health check.

Initial Test: Executed docker-compose up to verify the backend successfully connected to the initialized database.




 

 

 

 















Procedure - Part2 - DA2: Frontend Integration

Frontend Development: Built the React components (App.jsx, SearchForm.jsx, ScholarshipTable.jsx) for the user interface.

API Calls: Configured the search form to use axios.get with the proxy path /api/scholarships.

Dockerfile Creation: Created the multi-stage frontend/Dockerfile for efficient production image building.

Service Definition: Added the scholarscope-frontend service to docker-compose.yml.

 

 






Procedure - Part3 - DA3: Nginx Reverse Proxy and Final Deployment

Proxy Configuration: Created nginx/nginx.conf, defining the frontend and backend upstream servers and the traffic routing rules.

Nginx Service: Defined the scholarscope-nginx service in docker-compose.yml, mounting the configuration file and mapping port 80:80.

Build & Run: Executed docker-compose up --build to launch the complete four-container stack.

End-to-End Test: Accessed the application via Nginx (port 80) and performed a search query, verifying the correct flow through Frontend → Nginx → Backend → DB → Backend → Nginx → Frontend.

 

 






Modifications:

1. scholarscope-backend Container (Custom Build from python:3.10-slim)

1. Set Environment: ENV PYTHONDONTWRITEBYTECODE=1 and PYTHONUNBUFFERED=1 were set for improved Python behavior in containers.

2. Install Dependencies: The flask and psycopg2-binary packages were installed using pip install --no-cache-dir -r requirements.txt.

3. Application Logic: The project files, including app.py, were copied into the working directory /app.

4. Entrypoint: The container execution command was set to CMD ["python", "app.py"] to start the Flask server on port 8000.

2. scholarscope-frontend Container (Multi-Stage Build from node:18 to nginx:alpine)

1. Build Stage: Started from FROM node:18 AS build to provide the environment necessary to run npm install and npm run build.

2. Production Stage: Switched to the lightweight FROM nginx:alpine image.

3. Copy Assets: The compiled static files from the build stage (/app/dist) were copied into the final Nginx serving directory (/usr/share/nginx/html).

3. scholarscope-db Container (Official postgres:16 image)

1. Volume Mount: A host volume was mounted (./db/init.sql:/docker-entrypoint-initdb.d/init.sql) so that the PostgreSQL image's entrypoint script automatically executes the SQL file to create the schema and seed the database on first run.

2. Configuration: Environment variables (POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB) were passed via docker-compose.yml to configure the internal database settings.

4. scholarscope-nginx Container (Official nginx:latest image)

1. Configuration Override: The default Nginx configuration file was replaced by mounting a custom nginx/nginx.conf file from the host machine to define the reverse proxy logic.


Github link / dockerhub link of modified containers

Project GitHub Repository: https://github.com/Sree2111/scholarscope

DockerHub Links

Docker Hub (Frontend): https://hub.docker.com/r/sree2105/scholarscope-frontend

Docker Hub (Backend): https://hub.docker.com/r/sree2105/scholarscope-backend


Outcomes:

The completion of the three DAs resulted in the successful deployment of ScholarScope as a complete, fully containerized web application:

Fully Functional Stack: A four-service full-stack web application (Nginx → React / Flask → PostgreSQL) was deployed and proven functional using Docker.

Single-Command Deployment: The entire multi-container architecture is orchestrated with a single docker-compose up command, achieving complete environment portability.

Reverse Proxy Implementation: Successful implementation of Nginx to unify access and route traffic between the frontend and backend services via internal Docker networking.

Data Reliability: Demonstrated use of a Named Volume (scholarscope_pg_data) for robust data persistence and a health check on the database to manage service dependencies.

Efficiency: Gained hands-on experience with Dockerfiles, multi-stage builds (for the frontend), and writing production-grade Compose configurations.


Conclusion

This three-phase journey, culminating in the full containerization of the ScholarScope application, demonstrates the evolution of a modern software deployment pipeline. By leveraging Docker and Docker Compose, the project successfully overcame typical challenges like environment inconsistencies, managing dependencies, and creating a unified access point through the Nginx reverse proxy. The final architecture is robust, scalable, and portable—a true reflection of modern DevOps containerization workflows.


References and Acknowledgement

Base Images

PostgreSQL: Postgres Docker Hub

NGINX: Nginx Docker Hub

Python: Python Docker Hub

Node.js: Node Docker Hub

Institution & Course

Vellore Institute of Technology (VIT) – School of Computer Science and Engineering (SCOPE).

Course: Cloud Computing.

Special thanks to Dr. T Subbulakshmi maam for guidance and organizing the Docker Showdown event.

Tutorials & AI Assistance

IITB Docker Tutorial: https://spoken-tutorial.org/tutorial-search/?search_foss=Docker&search_language=

Google Gemini: Assisted with debugging, optimizing the Docker orchestration strategy, and structuring this final documentation report.

Research Paper (The Benefits of Containerization): https://www.researchgate.net/publication/388765972_Leveraging_Docker_Containers_for_Deployment_of_Web_Applications_in_Microservices_Architecture

Docker Compose Tutorial: https://www.youtube.com/watch?v=A9bA5HpOk30


Comments