πŸ«€ Building a Full-Stack Heart Disease Prediction System: ML, FastAPI, Docker, React, Render, GitHub Pages, and CI/CD

4 minute read

Published:

In this project, I built a complete end-to-end AI application that predicts the risk of heart failure using real clinical data. The goal was not just to train a machine learning model, but to transform it into a full-stack production-grade web application, deploy it using modern DevOps tools, and make it publicly available.

This system includes:

LayerTechnology
ML TrainingPython, Scikit-Learn, Matplotlib, Pandas
Backend APIFastAPI + Uvicorn
Model ServingPickle + Docker
Deployment (API)Render (Docker)
FrontendReact + Vite + Tailwind
Hosting (Frontend)GitHub Pages
CI/CDGitHub Actions
CommunicationREST API (JSON)

🧠 System Architecture

                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚    Machine Learning (ML)   β”‚
                        β”‚  Model training + Pickle   β”‚
                        β”‚  Python, Scikit-learn      β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                              Model.pkl exported
                                      β”‚
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚  FastAPI Backend (Render)  β”‚
                        β”‚ /predict endpoint (JSON)   β”‚
                        β”‚ Dockerized model serving   β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                                  REST API
                                      β”‚
                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                     β”‚        React Frontend           β”‚
                     β”‚   Hosted on GitHub Pages        β”‚
                     β”‚   Form β†’ API β†’ Prediction       β”‚
                     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                      β”‚
                                      β”‚
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚    End Users (Browser)     β”‚
                        β”‚ Web Interface for Testing  β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ File Structure

Heart_Disease/
│── .python-version
│── Dockerfile
│── pyproject.toml / requirements.txt
│── uv.lock
β”‚
│── heart_failure_clinical_records_dataset.csv
│── heart_failure_model.pkl
│── Mid_Term_Project.py       # Training Script
│── Mid_Term_Project.ipynb    # EDA Notebook
│── export_artifacts.py       # JSON/Graph exporting
│── main.py                   # FastAPI backend
β”‚
β”œβ”€β”€ figures/
β”‚   β”œβ”€β”€ correlation_matrix.png
β”‚   β”œβ”€β”€ histograms.png
β”‚   β”œβ”€β”€ death_event.png
β”‚
β”œβ”€β”€ heart-disease-app/        # FRONTEND (React+Vite)
β”‚   β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ DataHead.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ EDAGallery.jsx
β”‚   β”‚   β”‚   β”œβ”€β”€ ModelSummary.jsx
β”‚   β”‚   β”œβ”€β”€ App.jsx
β”‚   β”‚   β”œβ”€β”€ main.jsx
β”‚   β”‚   β”œβ”€β”€ index.css
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ vite.config.js
β”‚   β”œβ”€β”€ tailwind.config.js
β”‚   β”œβ”€β”€ postcss.config.js
β”‚
└── .github/
    └── workflows/
        └── deploy.yml        # CI/CD GitHub Actions

βš™οΈ Phase 1: Machine Learning Model Development

πŸ“₯ Install Dependencies

pip install pandas numpy scikit-learn matplotlib seaborn

πŸ§ͺ Load Dataset & Explore

import pandas as pd
df = pd.read_csv("heart_failure_clinical_records_dataset.csv")
print(df.head())
df.info()
df.describe()

πŸ“Š EDA Visualizations

import seaborn as sns
import matplotlib.pyplot as plt

sns.heatmap(df.corr(), annot=True)
plt.savefig('figures/correlation_matrix.png')

πŸ€– Model Training

python Mid_Term_Project.py

Inside Mid_Term_Project.py:

  • Model training
  • Cross-validation
  • Hyperparameter tuning
  • Save best model:
import pickle
pickle.dump(best_model, open("heart_failure_model.pkl", "wb"))

🌐 Phase 2: FastAPI Backend

πŸ“¦ Install FastAPI

pip install fastapi uvicorn pydantic gunicorn

πŸš€ Create API (main.py)

from fastapi import FastAPI
import pickle
import numpy as np

app = FastAPI()
model = pickle.load(open("heart_failure_model.pkl", "rb"))

@app.post("/predict")
def predict(request: dict):
    values = np.array([list(request.values())]).reshape(1,-1)
    prediction = model.predict(values)[0]
    probability = model.predict_proba(values)[0][1]
    return {"prediction": int(prediction),
            "probability": float(probability)}

▢️ Run Locally

uvicorn main:app --reload --port 8000

Visit: http://127.0.0.1:8000/docs


🐳 Phase 3: Dockerization

πŸ“ Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8000
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8000", "--log-file", "-"]

πŸ—οΈ Build Docker Image

docker build -t heart-disease-api .
docker run -p 8000:8000 heart-disease-api

πŸ“€ Push to Docker Hub

docker tag heart-disease-api mdislammazharul/heart-disease-api
docker push mdislammazharul/heart-disease-api

πŸš€ Phase 4: Deploy Backend using Render (Docker)

Steps:

1️⃣ Render site β†’ https://dashboard.render.com

2️⃣ New β†’ Web Service

3️⃣ Select Deploy from Docker

4️⃣ Use GitHub repo

5️⃣ Use start command auto-detected from Dockerfile.

6️⃣ Deploy β€” after build, get an API URL like:

https://heart-failure-prediction-qe7o.onrender.com/predict

🌐 Phase 5: React Frontend (Vite + Tailwind)

πŸ’» Create Project

npm create vite@latest heart-disease-app --template react
cd heart-disease-app
npm install

🎨 Install Tailwind

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

🌐 Call API from Frontend

In src/components/PredictForm.jsx:

const API_BASE = "https://heart-failure-prediction-qe7o.onrender.com/predict";

fetch(API_BASE, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(formData),
})
  .then((res) => res.json())
  .then((data) => setResult(data));

⚠️ Configure CORS on FastAPI (main.py)

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:5173",
        "https://mdislammazharul.github.io"
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

πŸš€ Deploy Frontend using GitHub Pages

npm install gh-pages --save-dev

In package.json:

"homepage": "https://mdislammazharul.github.io/Heart_Failure_Prediction/",
"scripts": {
  "deploy": "gh-pages -d dist"
}

Build and deploy:

npm run build
npm run deploy

Frontend is live at:

πŸ‘‰ https://mdislammazharul.github.io/Heart_Failure_Prediction/


πŸ”„ CI/CD with GitHub Actions

Create: .github/workflows/deploy.yml

name: Deploy to GitHub Pages

on:
  push:
    branches: ["main"]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm install
      - run: npm run build
      - uses: JamesIves/github-pages-deploy-action@v4
        with:
          folder: dist

🎯 Live Demo

πŸ”— Frontend: https://mdislammazharul.github.io/Heart_Failure_Prediction/

πŸ”— API Endpoint: https://heart-failure-prediction-qe7o.onrender.com/docs