Part of the MLOps Portfolio Series — Project 5 of 10
Deploys the XGBoost champion model from Project 4 as a production FastAPI service — containerised with Docker, tested with pytest, and ready for Cloud Run deployment.
| Resource | Link |
|---|---|
| 🚀 FastAPI App | src/api/app.py |
| 🏋️ Model Trainer | src/model/train.py |
| 🧪 API Tests | tests/test_api.py |
| 🐳 Dockerfile | Dockerfile |
| 🤖 CI/CD Workflow | .github/workflows/serving.yml |
| 📋 Requirements | requirements.txt |
Takes the champion XGBoost model from Project 4 and puts it in front of real users:
- Trains champion model on real UCI Bank Marketing data (41,188 rows)
- Serves predictions via FastAPI REST endpoints
- Containerises with Docker — multi-stage build, non-root user, health check
- Tests all endpoints with pytest (11 passing tests)
- CI/CD pipeline trains → tests → builds Docker → tests container on every push
| Property | Value |
|---|---|
| Algorithm | XGBoost (tuned with Optuna — Project 4) |
| Dataset | UCI Bank Marketing (41,188 rows, real data) |
| AUC | 0.8176 |
| Baseline AUC | 0.8174 (Project 1 RandomForest) |
| Features | 19 (duration dropped — leakage) |
| Target | Term deposit subscription (binary) |
| Method | Endpoint | Description |
|---|---|---|
| GET | / |
Welcome message |
| GET | /health |
Health check + model info |
| GET | /model-info |
Full model metadata |
| POST | /predict |
Single customer prediction |
| POST | /predict-batch |
Batch predictions |
curl -X POST "http://localhost:8000/predict" \
-H "Content-Type: application/json" \
-d '{
"age": 42,
"job": "admin.",
"marital": "married",
"education": "university.degree",
"default": "no",
"housing": "yes",
"loan": "no",
"contact": "cellular",
"month": "may",
"day_of_week": "mon",
"campaign": 2,
"pdays": 999,
"previous": 0,
"poutcome": "nonexistent",
"emp.var.rate": 1.1,
"cons.price.idx": 93.994,
"cons.conf.idx": -36.4,
"euribor3m": 4.857,
"nr.employed": 5191.0
}'{
"prediction": 0,
"probability": 0.0823,
"label": "No — will not subscribe",
"confidence": "High",
"model_version": "XGBoost-v1"
}mlops-model-serving/
├── src/
│ ├── api/
│ │ └── app.py # FastAPI app — 5 endpoints
│ └── model/
│ └── train.py # Train + save artifacts
├── tests/
│ └── test_api.py # 11 pytest tests
├── artifacts/ # model, feature_order, encoders, model_info
├── Dockerfile # Multi-stage build
├── .github/
│ └── workflows/
│ └── serving.yml # CI: train → test → docker build → test container
├── requirements.txt
└── Makefile
git clone https://github.com/jumma786/mlops-model-serving.git
cd mlops-model-serving
pip install -r requirements.txt
# Train model on real data
python src/model/train.py --data-path data/bank-additional-full.csv
# Run tests
make test
# Start API server
make run
# Open http://localhost:8000/docs# Build
make docker-build
# Run
make docker-run
# API available at http://localhost:8000# Build and push to GCR
gcloud builds submit --tag gcr.io/PROJECT_ID/mlops-model-serving
# Deploy to Cloud Run
gcloud run deploy mlops-model-serving \
--image gcr.io/PROJECT_ID/mlops-model-serving \
--platform managed \
--region europe-west2 \
--allow-unauthenticated| # | Project | Repo | Status |
|---|---|---|---|
| 1 | Multi-Model Tournament Pipeline | mlops-model-tournament | ✅ |
| 2 | Scheduled Retraining + DVC + MLflow | mlops-retraining-pipeline | ✅ |
| 3 | Feature Engineering as Versioned Artifact | mlops-feature-pipeline | ✅ |
| 4 | Hyperparameter Tuning with Optuna + MLflow | mlops-hyperparameter-tuning | ✅ |
| 5 | FastAPI + Docker + Cloud Run | mlops-model-serving | ✅ This repo |
| 6 | Feature Store with Feast + Redis | mlops-feature-store | 🔜 |
| 7 | Model Monitoring & Drift Detection | mlops-model-monitoring | 🔜 |
| 8 | A/B Testing Framework | mlops-ab-testing | 🔜 |
| 9 | Airflow Pipeline Orchestration | mlops-airflow-pipeline | 🔜 |
| 10 | Kubernetes ML Platform | mlops-k8s-platform | 🔜 |
- REST API serving — FastAPI with Pydantic validation
- Containerisation — Docker multi-stage build, non-root user
- CI/CD for serving — train → test → build → test container
- Input validation — Pydantic schemas reject invalid inputs
- Health checks — Docker HEALTHCHECK + /health endpoint
- Batch inference — /predict-batch for high-throughput use cases
Jumma Mohammad Teli — Data Analyst & ML Engineer
📍 Birmingham, UK
📧 jummamohammad477@gmail.com
🔗 LinkedIn | GitHub
Project 5 of 10 — MLOps Portfolio Series. Builds on Project 4 (Hyperparameter Tuning) by deploying the champion model as a production API.