New Course:Designing Production-Grade Deep Learning Pipelines, now on Udemy.Enroll
MLOps & Production Pipelines · ML Pipeline Orchestration

ChurnFlow: End-to-End MLOps Pipeline

A production-grade MLOps pipeline for telecom customer churn prediction — integrating FastAPI model serving, Docker Compose multi-service orchestration, and GitHub Actions CI/CD in a single end-to-end system.

Baseline Model Accuracy
Predictive Power
CI/CD
Fully Automated GitHub Actions Pipeline
View Code on GitHub

ArchitectureMLOps · Full Lifecycle PipelineBuilt WithFastAPI · EvidentlyAI · MLflow · Docker · GitHub Actions · scikit-learn · Python

The Problem

Most ML models never make it to production — and those that do degrade silently without anyone noticing

The gap between a trained ML model and a production ML system is one of the most underestimated challenges in applied machine learning.

A model that performs well in a notebook faces a gauntlet of production realities: it needs a serving endpoint that handles real-time requests, a monitoring layer that detects when input data drifts away from the training distribution, an automated retraining trigger that responds to that drift, an experiment tracking system that maintains a full audit trail of every model version, and a CI/CD pipeline that tests, builds, and deploys changes without manual intervention.

Without all of these components working together, the model either never ships or ships and silently degrades as the real world diverges from its training data — both outcomes that represent a complete failure to deliver ML value.

The Solution

A full MLOps lifecycle system — from training to serving to drift detection to CI/CD — built as a production-ready multi-service platform

ChurnFlow is an end-to-end MLOps pipeline for telecom customer churn prediction that demonstrates the full production ML lifecycle in a single integrated system. A scikit-learn Logistic Regression model is trained on telecom churn data, serialized with joblib, and served via a FastAPI REST endpoint at /predict for real-time inference.

MLflow tracks every experiment — parameters, metrics, and model artifacts — maintaining a complete versioned audit trail. EvidentlyAI monitors incoming prediction data for drift and automatically triggers model retraining when distribution shifts are detected.

A Docker Compose configuration orchestrates three separate containers — API, monitoring, and MLflow — as an isolated, reproducible multi-service environment.

GitHub Actions drives the CI/CD pipeline: on every merge to main, automated tests run via pytest, all three Docker images are built and validated, and the updated system is deployment-ready — all without manual intervention.

Key Outcome

A production-ready MLOps system that demonstrates the full ML engineering lifecycle — real-time serving, drift-triggered retraining, experiment tracking, multi-service containerization, and automated CI/CD — built around a telecom churn prediction model that achieves 80% accuracy and AUC of 84%.

Technical Deep Dive

Architecture & Design

MLOps Pipeline

Model Development

Step 1Data Ingestiondata_ingestion.py · Raw telecom churn data loading
Step 2Feature Engineeringfeature_engineering.py · sklearn Pipeline · StandardScaler · OneHotEncoder
Step 3Model Trainingtrain_model.py · Logistic Regression · 80% acc · AUC 84%
Experiment Tracking · MLflowVersioned Model RegistryLogs parameters, metrics, and artifacts for every training run · Full audit trail across model versions · Stored in mlruns/ · UI accessible at localhost:5000

Model Serving

REST API · FastAPIReal-Time Inference Endpointapp.py · Serves on-demand predictions at localhost:8000/predict · JSON request/response · joblib model loading · Swagger UI docs

Monitoring & Automated Retraining

Drift Detection · EvidentlyAIData & Prediction Monitoringmonitor.py · Monitors feature distributions vs. training baseline · Live dashboard at localhost:8001/view_report · Exports monitor_report_latest.html
Automated RetrainingDrift-Triggered Pipelineretrain.py · Triggered automatically on detected drift · Versioned .pkl saved to models/ · Run logged to version_log.csv

Containerization · Docker Compose

Container 1API Serviceapi.Dockerfile · FastAPI inference container
Container 2Monitoring Servicemonitor.Dockerfile · EvidentlyAI drift monitoring
Container 3MLflow Servicemlflow.Dockerfile · Experiment tracking UI + artifact store

CI/CD · GitHub Actions

Step 1 · On Push/PRAutomated Testspytest suite runs on every main branch merge
Step 2 · On PassDocker Build & ValidateAll 3 images built and validated automatically
Step 3 · On PassReady for DeploymentUpdated system deployment-ready — zero manual intervention

Stage by Stage

  1. Model Development

    Data Pipeline & Training

    py trains a scikit-learn Logistic Regression model achieving 80% accuracy and AUC of 84%. The trained model is serialized to the models/ directory via joblib for downstream serving.

  2. Experiment Tracking

    MLflow Model Registry

    Every training run is logged to MLflow — parameters, metrics, and model artifacts are stored in the mlruns/ directory and accessible through the MLflow UI at localhost:5000. This creates a complete, versioned audit trail across all training iterations, making it possible to compare runs, roll back to a previous version, and trace any production model to the exact data and code that produced it.

  3. Model Serving

    FastAPI REST Endpoint

    app.py exposes the trained model as a REST API at localhost:8000/predict, accepting JSON feature payloads and returning churn probability scores in real time. The endpoint loads the serialized model via joblib and is documented through an auto-generated Swagger UI — making it immediately consumable by downstream applications, dashboards, or internal tooling without any additional integration work.

  4. Monitoring

    EvidentlyAI Drift Detection

    py runs EvidentlyAI against incoming prediction data, comparing live feature distributions against the training baseline to detect data drift. html. pkl to the models/ directory, and hot-reloading the serving endpoint without manual intervention.

  5. Containerization

    Docker Compose Multi-Service

    Three dedicated Dockerfiles — api.Dockerfile, monitor.Dockerfile, mlflow.Dockerfile — define isolated containers for each service. docker-compose.yml orchestrates all three together, enabling the entire system to be spun up with a single docker compose up --build command. This ensures full environment reproducibility across development, testing, and deployment contexts.

  6. CI/CD

    GitHub Actions Automation

    Every push or pull request to main triggers the GitHub Actions pipeline — pytest runs the full test suite, and on a successful pass, all three Docker images are built and validated automatically. Artifacts are stored in both GitHub Actions and MLflow. The result is a system where code changes are tested and containerized without any manual build steps, keeping the deployment path clear of human bottlenecks.

Why It Works

Key Design Decisions

Decision 01

Three isolated containers prevent service coupling

Running the API, monitoring, and MLflow as separate Docker containers rather than a monolithic service means each component can be updated, scaled, or replaced independently. A change to the monitoring logic does not require rebuilding the API container. A new model version does not interrupt the drift detection service. This separation of concerns is a foundational production ML engineering principle that ChurnFlow demonstrates in practice.

Decision 02

Drift detection closes the retraining loop automatically

Without automated drift detection, a deployed model silently degrades as real-world data distribution shifts away from the training data — the most common failure mode for production ML systems. By connecting EvidentlyAI's drift reports directly to retrain.py, ChurnFlow ensures that model degradation triggers a response rather than just a report. The retraining loop closes automatically — new data, new model, new versioned .pkl saved to disk, updated endpoint.

Decision 03

CI/CD eliminates manual deployment as a production bottleneck

Manual deployment steps — building images, running tests — are a common source of deployment errors and a significant drag on iteration speed. By automating the entire sequence through GitHub Actions, ChurnFlow ensures that every code change that passes tests is automatically containerized and deployment-ready. This removes the human bottleneck from the deployment path and makes the system's release cycle as fast as the test suite.

Results & Metrics

What the system delivers

Model Accuracy
Baseline Logistic Regression on telecom churn dataset — validated on held-out test set
Predictive Power
Area under the ROC curve — strong discriminative power between churn and non-churn customers
CI/CD
Fully Automated Pipeline
GitHub Actions — automated testing, Docker build, and Docker Hub push on every main branch merge
  • Closed-loop drift detection and automated retraining

    EvidentlyAI continuously monitors incoming feature distributions against the training baseline. When drift is detected, retrain.py triggers automatically — retraining the model, versioning it in MLflow, and updating the serving endpoint without any manual intervention. The full retraining loop closes without human involvement, keeping the production model aligned with live data distributions.

  • Full system up in one command — docker compose up --build

    Three dedicated Dockerfiles define isolated, reproducible environments for the API, monitoring, and MLflow services. Docker Compose orchestrates all three together — the entire production stack can be spun up from scratch with a single command in any environment. This makes the system portable across development, staging, and production without environment-specific configuration changes.

  • Zero-touch deployment on every successful merge

    Every push to main triggers the GitHub Actions pipeline — pytest runs the full test suite, and on a successful pass all three Docker images are built and pushed to Docker Hub automatically. No manual build steps, no manual pushes, no deployment bottlenecks. Code changes move from commit to deployment-ready container without any developer intervention beyond the merge itself.

  • Complete versioned audit trail across every model iteration

    MLflow logs parameters, metrics, and model artifacts for every training and retraining run — creating a complete, searchable history of every model version the system has ever produced. Any production model can be traced back to the exact data, code, and hyperparameters that generated it, and any previous version can be restored and redeployed from the registry.

  • Real-time inference via documented REST API

    The FastAPI endpoint at localhost:8000/predict accepts JSON feature payloads and returns churn probability scores in real time, with auto-generated Swagger UI documentation making the API immediately consumable by downstream applications. Any tool or service that can make an HTTP POST request can integrate with the churn prediction system — no SDK, no custom client library required.

Tools

Tech Stack

TechnologyPurpose
scikit-learnLogistic Regression model training and evaluation
FastAPIREST API for real-time churn prediction inference
MLflowExperiment tracking, model versioning, and artifact storage
EvidentlyAIData drift detection with automated retraining trigger
Docker / Docker ComposeMulti-container orchestration — API, monitoring, and MLflow services
GitHub ActionsCI/CD pipeline — automated testing and Docker image builds on every push to main
joblibModel serialization and loading for serving
pandasData loading, imputation, splitting, and CSV I/O across all pipeline stages
pytestAutomated unit and integration testing within CI/CD pipeline
PythonCore language and system orchestration

Let's Build Something That Matters

If you have a decision that depends on predicting risk in a complex system, I'd like to hear about it.