ChurnReaper v2: From ML Dashboard to Cloud-Deployed Data Product

A while back I wrote about building ChurnReaper, a machine learning dashboard that predicts which customers are likely to leave a subscription service. That first version covered the core pieces: cleaning the data, training a churn model, and putting the results behind a basic interactive dashboard. It was enough to prove the idea worked.
ChurnReaper v2 picks up where that post left off. This time I didn't focus on the model itself — I focused on everything around it that turns a working project into something you can actually package, deploy, and hand to someone else. If v1 was about making it work, v2 was about making it shippable.
Where v1 Left Off
The first version already did the important data science work: customer features in, a churn prediction out, and a Plotly Dash dashboard to make those predictions readable instead of buried in a notebook. (If you want the full breakdown of the model and the data prep, that's all in the [first post].)
What it didn't do well was leave my laptop. Running locally is fine for a demo, but a real data product needs to run somewhere reliable, reproducibly, and be understandable to people who aren't me. That gap is what v2 set out to close.
What Changed in v2
Instead of bolting on more features, v2 was about the rest of the project lifecycle:
Containerizing the whole application with Docker so it runs the same way everywhere
Deploying it to a live AWS EC2 instance with a public URL
Documenting it properly — screenshots, a clear README, and a versioned GitHub release
The core stack carried over from v1: Python, pandas/NumPy, scikit-learn, and Plotly Dash. What v2 layered on top was Docker for packaging, AWS EC2 for hosting, and Git/GitHub for versioning and release management.
Dockerizing the Application
The first real step was getting ChurnReaper into a container. Locally, the project depended on a specific set of Python packages and versions, and "works on my machine" is exactly the problem Docker solves.
I wrote a Dockerfile that bundled the app, its dependencies, and the runtime into a single image, so the same container that runs on my laptop also runs on a remote server with no extra setup.
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8051
CMD ["python", "dashboard/app.py"]
This was the moment the project started feeling production-ready rather than experimental.
Deploying on AWS EC2
With a working Docker image, the next step was getting ChurnReaper v2 onto a server. I launched an AWS EC2 instance, installed Docker, moved the project setup to the instance, and ran the container so the dashboard could be accessed through a public URL.
The part that taught me the most was the networking. A dashboard that works perfectly on localhost will not automatically be reachable from the internet. A few pieces have to line up correctly:
The app has to bind to
0.0.0.0, not only127.0.0.1The Docker container port has to be mapped to the host port using
docker run -pThe EC2 security group has to allow inbound traffic on the dashboard port
In my case, the dashboard worked locally, but the public EC2 URL did not load until I opened inbound TCP traffic on port 8051 in the EC2 security group. That small debugging step helped me understand how local ports, container ports, and cloud firewall rules work together.
Once those pieces lined up, the dashboard was live through a public URL. That was the moment ChurnReaper v2 felt less like a local experiment and more like a real deployed application.
Documentation and the GitHub Release
The last piece of v2 was presentation. A project nobody can understand is hard to show off, so I added screenshots of the running dashboard to the README, wrote up how to run it, and cut a tagged GitHub release to mark this as a real, versioned milestone rather than just another commit.
This step is easy to skip and easy to undervalue, but it's often the first (and sometimes only) thing a reviewer or recruiter actually looks at.
What I Learned
The biggest takeaway from v2 was that the model is maybe half the work. Getting from a trained model to something deployable meant understanding Docker, EC2, port mapping, security groups, and the small differences between a local app and a remote one — none of which show up in a typical ML tutorial.
It reinforced something the first post only hinted at: a strong project isn't just an accurate model, it's a model that's packaged, reachable, and easy for someone else to understand.
What's Next
There's still plenty I'd like to add to ChurnReaper:
Model explainability, so the dashboard shows why a customer is flagged, not just that they are
Richer visualizations and better customer segmentation
User authentication so the deployed dashboard isn't wide open
For now, though, v2 took ChurnReaper from a model that worked to a product that ships — and that was the whole point.
Project Links
GitHub Repository: ChurnReaper
GitHub Release: ChurnReaper v2.0
Live Dashboard: Open ChurnReaper Dashboard
Previous Post: I Built a Machine Learning Dashboard That Predicts Which Customers Will Leave



