I've been working on deploying apps built with Streamlit, a rapid prototyping machine learning web framework, to Docker and then managed Kubernetes. These are notes on my experience figuring out a minimal deployment strategy. I started by using Streamlit's self-driving demo to illustrate deployment to Docker of a sample Streamlit application but was blocked by an application error in the end. Since then, I've deployed a more streamlined example app in the form of Maël Fabien's sample app to AKS(Azure Kubernetes Service.)
Today I am going to focus on how I went about Dockerizing a simple Streamlit app, the challenges I faced during doing so, the experience and methodology of the AKS deploy, and what I'd do differently or look to do in the future with this stack.
Using Docker to containerize Streamlit leans into the rapid development and deployment aspects of Streamlit, while leaving you not beholden to Streamlit Cloud, Streamlit's solution for deployment, allowing for more flexibility. To start, I had seen various strategies for Streamlit on Docker package management, but chose to use what felt like the simplest, tried, and true solution -- a requirements.txt file and pip install. This did lead to a rather long pip upgrade and install when initially building the image, something I'm going to look into best practices on mitigating. The actual Dockerfile is pretty simple conceptually, with some quirks.
I did face challenges along the way, especially around permissions with the non-root user running the entry point command and package installs. Originally using the self-driving demo, the non-root docker-usr had several permissions denied errors, including to the yolo3 weights critical for the image recognition service. I took away that it's important to remember Linux permissions when using the best practice of not running Docker as root. In retrospect, I would have versioned the libraries involved, used a slimmer image, and streamlined the entire process more among other improvements. I also am not sure if the config files and credential files for Streamlit are absolutely necessary, I'm going to experiment with dropping them as I focus on the AKS portion of this deployment.
With AKS, I had the Azure CLI set up and did a good amount of work through the CLI, which I wouldn't repeat, I'd use Terraform and Helm for AKS setup as I have in the past. The steps I took were to create a Resource Group on Azure, an Azure Container Registry, build and push the image I had a Dockerfile for, then created a small AKS cluster and created a secret for authentication on pulling the image from ACR. Setting up the Deployment, Service, and Ingress, that trinity of opening up to the world on Kubernetes, I used .yaml files and kubectl to apply them, along with Helm to install the NGINX ingress controller(Microsoft has a good guide here. As well, you can find those .yamls on the below-linked GitHub repo.)
This all worked, but in the future, I'd definitely work to streamline and automate the process using Terraform, Helm, and Ansible, or Jenkins as I explore those configuration technologies. This isn't a production deployment, and I've kept this post relatively code-light accordingly, you can find the code at my Github and poke around if this has gotten you interested.
In the end, AKS deployment of Streamlit was pretty streamlined, once I got through some blockers and focused on deploying a very simple app. I'd encourage you if, like me, you're interested in data science apps and DevOps both, to check out Streamlit and integrating it to deployment with AKS. Searching for solutions to deploy Streamlit in the past has been difficult, but with Streamlit Cloud and an active community, this rapid development framework is now going to save you some of that valuable time you spent reading this in its potential for rapid deployment. Reach out and/or comment if you have any questions or any thoughts this blog post brought to mind!