{"id":818,"date":"2023-08-14T07:24:48","date_gmt":"2023-08-14T07:24:48","guid":{"rendered":"https:\/\/tbekk.com\/devstream\/?p=818"},"modified":"2023-08-14T07:26:51","modified_gmt":"2023-08-14T07:26:51","slug":"mlops-mastering-machine-learning-deployment-an-intro-to-docker-kubernetes-helm-and-modern-web-frameworks-end-to-end-project","status":"publish","type":"post","link":"https:\/\/tbekk.com\/devstream\/2023\/08\/14\/mlops-mastering-machine-learning-deployment-an-intro-to-docker-kubernetes-helm-and-modern-web-frameworks-end-to-end-project\/","title":{"rendered":"MLOps: Mastering Machine Learning Deployment: An Intro to Docker, Kubernetes, Helm, and Modern Web Frameworks-End To End Project"},"content":{"rendered":"\n<p>Streamlit, Gradio, FastAPI, Flask, Terraform, Spinnaker, Puppet<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-light-gray-color has-alpha-channel-opacity has-light-gray-background-color has-background is-style-wide\"\/>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em><strong>Link: <\/strong><\/em><a href=\"https:\/\/levelup.gitconnected.com\/mlops-mastering-machine-learning-deployment-an-intro-to-docker-kubernetes-helm-and-modern-web-b14dd140a9bf\"><em>MLops<\/em><\/a><\/li>\n\n\n\n<li><em><strong>Author: <\/strong><\/em><a href=\"https:\/\/esenthil.medium.com\/?source=post_page-----b14dd140a9bf--------------------------------\"><em>Senthil E<\/em><\/a><\/li>\n\n\n\n<li><em><strong>Publication date: <\/strong>August th, 2023<\/em><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-light-gray-color has-alpha-channel-opacity has-light-gray-background-color has-background is-style-wide\"\/>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"1a72\">Introduction:<\/h1>\n\n\n\n<p id=\"bd06\">In the dynamic world of machine learning, the journey from developing a model to putting it into production is often seen as intricate and multifaceted. However, with the advent of tools like Docker, Kubernetes and user-friendly web frameworks such as FastAPI, Streamlit, and Gradio, this journey has become more streamlined than ever. Coupled with the power of GitHub Actions for continuous integration and deployment, we now have an ecosystem that supports rapid, efficient, and scalable machine learning applications. This article provides a concise guide on the essential commands for these tools, aiming to bridge the gap between model development and seamless deployment. Whether you\u2019re a seasoned data scientist looking to venture into the deployment realm or a budding developer eager to integrate machine learning into web applications, this guide offers a foundational understanding to propel your endeavors.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*GYQsHueza4ZaD0ttckx_Sg.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"b932\">Contents:<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong><em>Docker<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Kubernetes<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Helm<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>GitHub Actions<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Streamlit<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Python Flask<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Gradio<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>FastAPI<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Terraform<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Spinnaker<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Crossplane<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Puppet<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Conclusion<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>References<\/em><\/strong><\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*jg2hvRQIxSLcRhKsPo-jZw.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*6p1q01YmK56ZWz9Er_bAhQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"1d93\">Docker:<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4928\">What is Docker?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Definition:&nbsp;<\/strong>Docker is a platform that allows developers to package applications and their dependencies into containers.<\/li>\n\n\n\n<li><strong>Containerization:&nbsp;<\/strong>Unlike traditional virtualization, Docker containers share the host system\u2019s OS kernel rather than including their own operating system. This makes them lightweight and fast.<\/li>\n\n\n\n<li><strong>Portability:<\/strong>&nbsp;Containers ensure that applications run consistently across multiple environments, from a developer\u2019s local machine to various production setups.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*gVXTsssGVjQbqT-fwRkzpg.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0ee8\">Why is Docker Essential for ML Deployment?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Environment Consistency:<\/strong>&nbsp;Ensures that the model runs with the same dependencies and libraries in development, testing, and production.<\/li>\n\n\n\n<li>Reduces the \u201cIt works on my machine\u201d problem.<\/li>\n\n\n\n<li><strong>Scalability:&nbsp;<\/strong>Docker containers can be easily scaled up or down based on the application\u2019s demand.<\/li>\n\n\n\n<li><strong>Isolation:<\/strong>&nbsp;ML models, especially those in a microservices architecture, might have different dependencies. Docker isolates these dependencies to avoid conflicts.<\/li>\n\n\n\n<li><strong>Version Control for Environments:<\/strong>&nbsp;Just as with code, Docker allows for versioning of environments. If a newer library version breaks the model, one can easily revert to the older, working container version.<\/li>\n\n\n\n<li><strong>Efficient Resource Utilization:<\/strong>&nbsp;Docker containers are lightweight and use resources efficiently, which is essential for deploying multiple ML models on the same infrastructure.<\/li>\n\n\n\n<li><strong>Integration with Modern Deployment Pipelines:<\/strong>&nbsp;Docker seamlessly integrates with CI\/CD tools and orchestration systems like Kubernetes, facilitating automated testing and deployment.<\/li>\n\n\n\n<li><strong>Collaboration:&nbsp;<\/strong>Data scientists, ML engineers, and developers can share Docker containers, ensuring everyone is working in a consistent environment.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"f115\">Docker Installation:<\/h2>\n\n\n\n<p id=\"1512\">Check Docker documentation installation<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.docker.com\/get-docker\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/docs.docker.com\/get-docker\/\" rel=\"noreferrer noopener\" target=\"_blank\">Get Docker<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/docs.docker.com\/get-docker\/\" rel=\"noreferrer noopener\" target=\"_blank\">Download and install Docker on the platform of your choice, including Mac, Linux, or Windows.<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.docker.com\/get-docker\/\" rel=\"noreferrer noopener\" target=\"_blank\">docs.docker.com<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"262b\">Docker Version:<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker --version<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5a4c\">Creating a Dockerfile for Python &amp; Machine Learning<\/h2>\n\n\n\n<p id=\"78e9\">The Dockerfile defines what goes into your container. Here\u2019s an example Dockerfile for a Python machine learning environment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Use an official Python runtime as base image<br>FROM python:3.8-slim<br><br># Set the working directory inside the container<br>WORKDIR \/usr\/src\/app<br><br># Install essential libraries and tools<br>RUN apt-get update &amp;&amp; \\<br>    apt-get install -y build-essential<br><br># Copy the requirements.txt into the container<br>COPY requirements.txt .<br><br># Install Python dependencies<br>RUN pip install --no-cache-dir -r requirements.txt<br><br># Command to run when the container starts<br>CMD [\"python\", \"your_script.py\"]<\/pre>\n\n\n\n<p id=\"c84a\"><strong>Dockerfile Breakdown:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Base Image:<\/li>\n\n\n\n<li><code><strong>FROM python:3.8-slim<\/strong><\/code><\/li>\n\n\n\n<li>This instructs Docker to use the official Python 3.8 image in its \u201cslim\u201d variant as the starting point for this container. The slim version is a lighter version of the image with fewer pre-installed tools and smaller size.<\/li>\n\n\n\n<li>Setting Working Directory:<\/li>\n\n\n\n<li><code><strong>WORKDIR \/usr\/src\/app<\/strong><\/code><\/li>\n\n\n\n<li>This sets the working directory inside the container to&nbsp;<code><strong>\/usr\/src\/app<\/strong><\/code>. All subsequent commands will be run from this directory.<\/li>\n\n\n\n<li>Installing Essential Libraries:<\/li>\n\n\n\n<li><code><strong>RUN apt-get update &amp;&amp; \\<\/strong><\/code><\/li>\n\n\n\n<li><code><strong>apt-get install -y build-essential<\/strong><\/code><\/li>\n\n\n\n<li>This updates the package lists for upgrades and new package installations. After updating, it installs the \u201cbuild-essential\u201d package, which contains compilers and libraries essential for building software.<\/li>\n\n\n\n<li>Copying Requirements:<\/li>\n\n\n\n<li><code><strong>COPY requirements.txt&nbsp;<\/strong>.<\/code><\/li>\n\n\n\n<li>This command takes the&nbsp;<code><strong>requirements.txt<\/strong><\/code>&nbsp;file from your current directory (on your host machine) and copies it to the working directory inside the container (<code><strong>\/usr\/src\/app<\/strong><\/code>).<\/li>\n\n\n\n<li>Installing Python Dependencies:<\/li>\n\n\n\n<li><code><strong>RUN pip install --no-cache-dir -r requirements.txt<\/strong><\/code><\/li>\n\n\n\n<li>Using pip, this command installs the Python libraries listed in the&nbsp;<code><strong>requirements.txt<\/strong><\/code>&nbsp;file. The&nbsp;<code><strong>--no-cache-dir<\/strong><\/code>&nbsp;option ensures pip won&#8217;t store any cache, keeping the container lightweight.<\/li>\n\n\n\n<li>Startup Command:<\/li>\n\n\n\n<li><code><strong>CMD [\"python\", \"your_script.py\"]<\/strong><\/code><\/li>\n\n\n\n<li>Specifies the command that should run when the container starts. In this case, it runs the Python script&nbsp;<code><strong>your_script.py<\/strong><\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0731\">Requirements File:<\/h2>\n\n\n\n<p id=\"c916\">Your&nbsp;<code>requirements.txt<\/code>&nbsp;might look something like this for a machine learning project:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">numpy==1.19.5<br>pandas==1.1.5<br>tensorflow==2.4.1<br>scikit-learn==0.24.1<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"e755\">Building a Docker Image<\/h2>\n\n\n\n<p id=\"7cc0\">To create a Docker image from your Dockerfile:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker build -t ml-python-image .<\/pre>\n\n\n\n<p id=\"cef3\">The&nbsp;<code>-t<\/code>&nbsp;flag assigns a tag or name to the image, and the&nbsp;<code>.<\/code>&nbsp;specifies the directory containing your Dockerfile.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"b193\">Running a Docker Container<\/h2>\n\n\n\n<p id=\"99b0\">To initiate a container from your image:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker run --name ml-python-container ml-python-image<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"c3c4\">Viewing Running Containers<\/h2>\n\n\n\n<p id=\"8108\">To see a list of all running containers:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker ps<\/pre>\n\n\n\n<p id=\"a738\">For all containers, including those that aren\u2019t running:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker ps -a<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5cf3\">Stopping and Removing Containers<\/h2>\n\n\n\n<p id=\"0a44\">To stop a running container:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker stop ml-python-container<\/pre>\n\n\n\n<p id=\"fabe\">To remove a stopped container:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker rm ml-python-container<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"681e\">Sharing your Docker Image<\/h2>\n\n\n\n<p id=\"e032\">You can share your Docker image using Docker Hub, a cloud service for sharing container images. First, log in:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker login<\/pre>\n\n\n\n<p id=\"706a\">Then, tag your image:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker tag ml-python-image:latest username\/ml-python-image:latest<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bd85\">Finally, push the image:<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker push username\/ml-python-image:latest<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"604c\">Pulling and Running Shared Images<\/h2>\n\n\n\n<p id=\"b970\">You or others can then pull the image:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker pull username\/ml-python-image:latest<\/pre>\n\n\n\n<p id=\"ea8b\">And run it:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker run --name new-ml-python-container username\/ml-python-image:latest<\/pre>\n\n\n\n<p id=\"01d9\">C<strong><em>heck out my article about Docker and Kubernetes if you want to know more :<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-dockers-and-kubernetes-essentials-for-a-data-scientist-8bc7b5866957\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-dockers-and-kubernetes-essentials-for-a-data-scientist-8bc7b5866957\" rel=\"noreferrer noopener\" target=\"_blank\">MLOps-Dockers and Kubernetes Essentials for a Data Scientist<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-dockers-and-kubernetes-essentials-for-a-data-scientist-8bc7b5866957\" rel=\"noreferrer noopener\" target=\"_blank\">Introduction<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-dockers-and-kubernetes-essentials-for-a-data-scientist-8bc7b5866957\" rel=\"noreferrer noopener\" target=\"_blank\">medium.com<\/a><\/p>\n\n\n\n<p id=\"41ee\">All in one<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># General<br>docker --version                 # Version Information<br>docker info                      # Docker Configuration Info<br><br># Images<br>docker images                    # List Images<br>docker build -t [image-name]:[tag] .   # Build an Image<br>docker rmi [image-name]:[tag]          # Remove an Image<br>docker pull [image-name]               # Pull an Image<br><br># Containers<br>docker ps                        # List Running Containers<br>docker ps -a                     # List All Containers<br>docker run -d -p [host-port]:[container-port] [image-name]  # Start a Container<br>docker stop [container-id]       # Stop a Container<br>docker rm [container-id]         # Remove a Container<br>docker logs [container-id]       # View Container Logs<br><br># Docker Compose (if you're using it)<br>docker-compose up               # Start Services<br>docker-compose down             # Stop Services<br><br># Maintenance<br>docker system prune             # Remove All Unused Containers, Networks, and Images<br>docker volume prune             # Remove All Unused Volumes<br>docker system df                # Check Docker Disk Usage<br><br># Dockerfile Basics (For reference, not executable as commands)<br># FROM [base-image]              # Base Image<br># WORKDIR \/path\/to\/directory    # Set Working Directory<br># RUN command                   # Run Commands<br># COPY source destination       # Copy Files<br># EXPOSE port                   # Expose Port<br># CMD [\"executable\", \"param1\", \"param2\"] # Default Command<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"b7d1\">Kubernetes:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*ZubgBfZJ6tv0pyAULubp8g.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9d8e\">Kubernetes Basics<\/h2>\n\n\n\n<p id=\"88d4\">1.&nbsp;<strong>Nodes and Clusters:<\/strong>&nbsp;A node is a machine, VM, or cloud instance, and a cluster is a group of nodes managed by Kubernetes. The Master node manages the cluster while Worker nodes run the applications.<\/p>\n\n\n\n<p id=\"493a\">2.<strong>&nbsp;Pods:<\/strong>&nbsp;The smallest deployable units in Kubernetes are pods. A pod can host multiple containers that form a single unit of deployment.<\/p>\n\n\n\n<p id=\"ef19\">3.&nbsp;<strong>Services:&nbsp;<\/strong>A Kubernetes Service is an abstract way to expose an application running on a set of Pods.<\/p>\n\n\n\n<p id=\"e893\">4.&nbsp;<strong>Deployments:<\/strong>&nbsp;This is a higher-level concept that manages the desired state of pods and replica sets.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1247\">Setting up Kubernetes:<\/h2>\n\n\n\n<p id=\"5fc6\">Kubernetes can be set up on local machines using Minikube or on cloud platforms. Cloud providers like AWS, GCP, and Azure offer managed Kubernetes services like EKS, GKE, and AKS, respectively.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"e1f7\">Deploying a Machine Learning Model on Kubernetes:<\/h2>\n\n\n\n<p id=\"efd1\">1.&nbsp;<strong>Containerize your Model<\/strong>: Before deploying on Kubernetes, your model needs to be containerized. Docker is typically used for this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM python:3.8-slim<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>WORKDIR \/app<\/strong><strong>COPY requirements.txt .<\/strong><strong>RUN pip install --no-cache-dir -r requirements.txt<\/strong><strong>COPY . \/app<\/strong><strong>CMD [\"python\", \"app.py\"]<\/strong><\/pre>\n\n\n\n<p id=\"2ce3\">This Dockerfile assumes you have an&nbsp;<code>app.py<\/code>&nbsp;that serves your model, perhaps using a framework like Flask or FastAPI.<\/p>\n\n\n\n<p id=\"fc0c\">Build and push your Docker image:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker build -t username\/ml-model:v1 .<br>$ docker push username\/ml-model:v1<\/pre>\n\n\n\n<p id=\"b923\">2.&nbsp;<strong>Create a Deployment Configuration:<\/strong>&nbsp;Define a deployment.yaml for Kubernetes:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: apps\/v1<br>kind: Deployment<br>metadata:<br>  name: ml-model-deployment<br>spec:<br>  replicas: 3<br>  selector:<br>    matchLabels:<br>      app: ml-model<br>  template:<br>    metadata:<br>      labels:<br>        app: ml-model<br>    spec:<br>      containers:<br>      - name: ml-model<br>        image: username\/ml-model:v1<br>        ports:<br>        - containerPort: 5000<\/pre>\n\n\n\n<p id=\"9224\"><strong>Kubernetes Deployment Manifest Breakdown:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>API Version:<\/strong><\/li>\n\n\n\n<li><code><strong>apiVersion: apps\/v1<\/strong><\/code><\/li>\n\n\n\n<li>Specifies the Kubernetes API version to use. For deployments, \u201capps\/v1\u201d is commonly used.<\/li>\n\n\n\n<li><strong>Kind:<\/strong><\/li>\n\n\n\n<li><code><strong>kind: Deployment<\/strong><\/code><\/li>\n\n\n\n<li>Indicates the kind of Kubernetes resource we want to create. In this case, it\u2019s a \u201cDeployment\u201d, which ensures that a specified number of pod replicas are running at any given time.<\/li>\n\n\n\n<li><strong>Metadata:<\/strong><\/li>\n\n\n\n<li><code>metadata:<\/code><\/li>\n\n\n\n<li>Contains data that helps uniquely identify the Deployment object.<\/li>\n\n\n\n<li><code><strong>name: ml-model-deployment<\/strong><\/code><\/li>\n\n\n\n<li>Names the deployment as \u201cml-model-deployment\u201d.<\/li>\n\n\n\n<li><strong>Spec (Specification):<\/strong><\/li>\n\n\n\n<li><code><strong>spec:<\/strong><\/code><\/li>\n\n\n\n<li>Defines the desired state for the deployment.<\/li>\n\n\n\n<li><code><strong>replicas: 3<\/strong><\/code><\/li>\n\n\n\n<li>Specifies that three replicas (instances) of the application should be running.<\/li>\n\n\n\n<li><strong>Selector:<\/strong><\/li>\n\n\n\n<li><code><strong>selector:<\/strong><\/code><\/li>\n\n\n\n<li>Helps the Deployment find which Pods to manage.<\/li>\n\n\n\n<li><code><strong>matchLabels:<\/strong><\/code><\/li>\n\n\n\n<li>Defines the selection criteria. It should match the labels defined in the Pod template.<\/li>\n\n\n\n<li><code><strong>app: ml-model<\/strong><\/code><\/li>\n\n\n\n<li>The Deployment manages Pods with the label \u201capp\u201d set to \u201cml-model\u201d.<\/li>\n\n\n\n<li>Template:<\/li>\n\n\n\n<li><code><strong>template:<\/strong><\/code><\/li>\n\n\n\n<li>Contains the Pod definition.<\/li>\n\n\n\n<li><code><strong>metadata:<\/strong><\/code><\/li>\n\n\n\n<li>Contains metadata for the Pod.<\/li>\n\n\n\n<li><code><strong>labels:<\/strong><\/code><\/li>\n\n\n\n<li><code><strong>app: ml-model<\/strong><\/code><\/li>\n\n\n\n<li>Sets the label \u201capp\u201d to \u201cml-model\u201d for the Pods. This should match the&nbsp;<code>matchLabels<\/code>&nbsp;section above.<\/li>\n\n\n\n<li>Containers:<\/li>\n\n\n\n<li><code><strong>containers:<\/strong><\/code><\/li>\n\n\n\n<li>Defines the container(s) that should be started when the Pod is instantiated.<\/li>\n\n\n\n<li><code><strong>- name: ml-model<\/strong><\/code><\/li>\n\n\n\n<li>Names the container \u201cml-model\u201d.<\/li>\n\n\n\n<li><code><strong>image: username\/ml-model:v1<\/strong><\/code><\/li>\n\n\n\n<li>Specifies the Docker image to use for the container. Here, it references version \u201cv1\u201d of an image named \u201cml-model\u201d from a repository belonging to \u201cusername\u201d.<\/li>\n\n\n\n<li><code><strong>ports:<\/strong><\/code><\/li>\n\n\n\n<li>Lists the network ports the container will use.<\/li>\n\n\n\n<li><code><strong>- containerPort: 5000<\/strong><\/code><\/li>\n\n\n\n<li>Specifies that the container will listen on port 5000. This would be the port where your ML model\u2019s serving API (e.g., a Flask or FastAPI application) is listening.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"85fa\">3. Deploy on Kubernetes:<\/h2>\n\n\n\n<p id=\"bb81\">Apply the deployment:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ kubectl apply -f deployment.yaml<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"292e\">4. Expose Your Model:<\/h2>\n\n\n\n<p id=\"a617\">To access your model, expose it using a service:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ kubectl expose deployment ml-model-deployment --type=LoadBalancer --port=80 --target-port=5000<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>expose<\/strong><\/code>:<\/li>\n\n\n\n<li>This tells&nbsp;<code>kubectl<\/code>&nbsp;that you want to expose a resource (in this case, a deployment) as a network service.<\/li>\n\n\n\n<li><code><strong>deployment ml-model-deployment<\/strong><\/code>:<\/li>\n\n\n\n<li>Specifies the type of the resource (<code>deployment<\/code>) and the name of that resource (<code>ml-model-deployment<\/code>) you want to expose.<\/li>\n\n\n\n<li><code><strong>--type=LoadBalancer<\/strong><\/code>:<\/li>\n\n\n\n<li>This specifies the type of the service you want to create. In this case, a&nbsp;<code>LoadBalancer<\/code>&nbsp;service is being requested. When used in cloud environments (like AWS, GCP, or Azure), this typically provisions a cloud load balancer to distribute network traffic to all the Pods associated with this service.<\/li>\n\n\n\n<li><code><strong>--port=80<\/strong><\/code>:<\/li>\n\n\n\n<li>Defines the port on which the service will listen. This means external traffic will come into the service on this port.<\/li>\n\n\n\n<li><code><strong>--target-port=5000<\/strong><\/code>:<\/li>\n\n\n\n<li>Specifies the port on the pod to which the service should forward the traffic. In the context of the earlier deployment, our application inside the container listens on port&nbsp;<code>5000<\/code>. So, external traffic coming in on port&nbsp;<code>80<\/code>&nbsp;(as specified by&nbsp;<code>--port<\/code>) will be forwarded to port&nbsp;<code>5000<\/code>&nbsp;on the pods.<\/li>\n<\/ul>\n\n\n\n<p id=\"ea63\"><strong>Retrieve the service URL:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ kubectl get services<\/pre>\n\n\n\n<p id=\"4992\">You can then access your machine learning model via the provided URL.<\/p>\n\n\n\n<p id=\"7de2\"><strong>5. Scaling Your Deployment:<\/strong><\/p>\n\n\n\n<p id=\"b4de\">Kubernetes makes it easy to scale your deployments:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ kubectl scale deployment ml-model-deployment --replicas=5<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>scale<\/strong><\/code><strong>:<\/strong><\/li>\n\n\n\n<li>This tells&nbsp;<code>kubectl<\/code>&nbsp;that you intend to change the number of replicas (i.e., adjust the scale) for a particular resource, in this case, a deployment.<\/li>\n\n\n\n<li><code><strong>deployment ml-model-deployment<\/strong><\/code>:<\/li>\n\n\n\n<li>Specifies the type of the resource (<code>deployment<\/code>) and the name of that resource (<code>ml-model-deployment<\/code>) that you want to scale.<\/li>\n\n\n\n<li><code><strong>--replicas=5<\/strong><\/code>:<\/li>\n\n\n\n<li>Specifies the desired number of replicas you wish to have for the deployment. This means Kubernetes will ensure that there are 5 identical pods (replicas) running for the&nbsp;<code>ml-model-deployment<\/code>.<\/li>\n<\/ul>\n\n\n\n<p id=\"6092\">Kubernetes provides a robust environment for deploying machine learning models, ensuring they\u2019re highly available and scalable.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*76IKwd5-B6S9VcbGw7jdhA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<p id=\"5f80\">C<strong><em>heck out my article about an End to End project using Docker and Kubernetes:<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-end-to-end-machine-learning-pipeline-cicd-1a7907698a8e\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-end-to-end-machine-learning-pipeline-cicd-1a7907698a8e\" rel=\"noreferrer noopener\" target=\"_blank\">MLOps End-To-End Machine Learning Pipeline-CICD<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-end-to-end-machine-learning-pipeline-cicd-1a7907698a8e\" rel=\"noreferrer noopener\" target=\"_blank\">The main objective of this project is to automate the whole machine learning app deployment process. To implement this\u2026<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/medium.com\/analytics-vidhya\/mlops-end-to-end-machine-learning-pipeline-cicd-1a7907698a8e\" rel=\"noreferrer noopener\" target=\"_blank\">medium.com<\/a><\/p>\n\n\n\n<p id=\"9892\">All in one go:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Cluster Info<br>kubectl cluster-info<br><br># Get resources<br>kubectl get nodes<br>kubectl get pods<br>kubectl get services<br>kubectl get deployments<br><br># Describe resources<br>kubectl describe node &lt;node-name&gt;<br>kubectl describe pod &lt;pod-name&gt;<br>kubectl describe service &lt;service-name&gt;<br>kubectl describe deployment &lt;deployment-name&gt;<br><br># Create resources<br>kubectl create -f &lt;filename.yaml&gt;<br>kubectl apply -f &lt;filename.yaml&gt;   # idempotent version of 'create'<br><br># Delete resources<br>kubectl delete -f &lt;filename.yaml&gt;<br>kubectl delete pod &lt;pod-name&gt;<br>kubectl delete service &lt;service-name&gt;<br>kubectl delete deployment &lt;deployment-name&gt;<br><br># Logs &amp; Debugging<br>kubectl logs &lt;pod-name&gt;<br>kubectl exec -it &lt;pod-name&gt; -- \/bin\/bash<br><br># Scale deployments<br>kubectl scale deployment &lt;deployment-name&gt; --replicas=&lt;number&gt;<br><br># Rolling updates and rollbacks<br>kubectl set image deployment\/&lt;deployment-name&gt; &lt;container-name&gt;=&lt;new-image&gt;<br>kubectl rollout history deployment\/&lt;deployment-name&gt;<br>kubectl rollout undo deployment\/&lt;deployment-name&gt;<br><br># Configuration<br>kubectl config view<br>kubectl config use-context &lt;context-name&gt;<br><br># Namespace operations<br>kubectl get namespaces<br>kubectl create namespace &lt;namespace-name&gt;<br>kubectl delete namespace &lt;namespace-name&gt;<br>kubectl get pods --namespace=&lt;namespace-name&gt;<br><br># Port forward<br>kubectl port-forward &lt;pod-name&gt; &lt;local-port&gt;:&lt;pod-port&gt;<\/pre>\n\n\n\n<p id=\"0fba\"><strong><em>Check out my article on Yaml for more details:<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/betterprogramming.pub\/everything-you-need-to-know-about-yaml-fdbb7acf6db6\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/betterprogramming.pub\/everything-you-need-to-know-about-yaml-fdbb7acf6db6\" rel=\"noreferrer noopener\" target=\"_blank\">Everything You Need to Know About YAML<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/betterprogramming.pub\/everything-you-need-to-know-about-yaml-fdbb7acf6db6\" rel=\"noreferrer noopener\" target=\"_blank\">Syntax, data types, styling, utilities, and more<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/betterprogramming.pub\/everything-you-need-to-know-about-yaml-fdbb7acf6db6\" rel=\"noreferrer noopener\" target=\"_blank\">betterprogramming.pub<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"44a5\">Helm:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*saKiJE5Y3qRz_UgSc93HVg.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"51dc\">Introduction to Helm:<\/h2>\n\n\n\n<p id=\"821a\">Helm is often dubbed as the package manager for Kubernetes. With machine learning models becoming more complex and the infrastructure around them growing larger, Helm simplifies the deployment process.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Charts:<\/strong>&nbsp;Helm uses \u201ccharts\u201d, which are packages of pre-configured Kubernetes resources. Imagine them as a packaged application.<\/li>\n\n\n\n<li><strong>Releases:&nbsp;<\/strong>When a chart is deployed on Kubernetes, it\u2019s called a release.<\/li>\n\n\n\n<li><strong>Simplicity:<\/strong>&nbsp;Instead of handling several different Kubernetes manifest files, you only need to manage a singular Helm chart.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"c599\">Setting Up Helm:<\/h2>\n\n\n\n<p id=\"83e8\">Before you can dive into deploying your ML model using Helm, you need to set it up.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Install Helm:&nbsp;<\/strong>Download and install Helm from the official website or use a package manager like&nbsp;<code>brew<\/code>.<\/li>\n\n\n\n<li><strong>Initialize Helm:<\/strong>&nbsp;Once installed, run&nbsp;<code>helm init<\/code>&nbsp;to set up the Helm environment.<\/li>\n\n\n\n<li><strong>Add Repositories:<\/strong>&nbsp;Helm charts are stored in repositories. Add the required repositories using&nbsp;<code>helm repo add<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"caa2\">Basic Helm Commands for ML Deployment<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Searching for Charts:&nbsp;<code>helm search repo<\/code>&nbsp;lets you find charts in your added repositories.<\/li>\n\n\n\n<li>Install a Chart:&nbsp;<code>helm install [chart-name]<\/code>&nbsp;will deploy the chart onto your Kubernetes cluster.<\/li>\n\n\n\n<li>Upgrading and Rolling Back: Changed something in your ML model?&nbsp;<code>helm upgrade<\/code>&nbsp;lets you upgrade your release with the newer chart. Made a mistake?&nbsp;<code>helm rollback<\/code>&nbsp;will revert to a previous version.<\/li>\n\n\n\n<li>Deleting a Release:&nbsp;<code>helm delete [release-name]<\/code>&nbsp;will remove the release from Kubernetes.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"66b5\">Deploying an ML Model using Helm<\/h2>\n\n\n\n<p id=\"fad9\">Let\u2019s take a hypothetical scenario where you have an ML model for image recognition:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prepare the Model: Train your model and expose it as an API (using Flask, FastAPI, Streamlit, etc.).<\/li>\n\n\n\n<li>Dockerize the Model: Create a Docker image of your ML application.<\/li>\n\n\n\n<li>Create a Helm Chart: Structure a Helm chart for your ML model, ensuring to define necessary resources like Deployments, Services, and any ConfigMaps or Secrets if needed.<\/li>\n\n\n\n<li>Deployment: Deploy your ML model using&nbsp;<code>helm install [chart-name]<\/code>. Kubernetes will create the resources defined in the chart.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0d5b\">Benefits of Using Helm for ML Deployments<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Version Control:&nbsp;<\/strong>Helm charts are versioned, ensuring you can manage different versions of your ML application seamlessly.<\/li>\n\n\n\n<li><strong>Atomic Deployments:<\/strong>&nbsp;Helm ensures that releases are atomic. This means either all resources are successfully deployed, or none are, ensuring consistent states.<\/li>\n\n\n\n<li><strong>Reusability and Sharing:<\/strong>&nbsp;You can easily package and share Helm charts. This is beneficial if you have similar deployment structures across different ML models or teams.<\/li>\n\n\n\n<li><strong>Complex Deployments Simplified:<\/strong>&nbsp;ML workflows can be intricate, especially when combined with data pipelines. Helm allows defining complex workflows in a maintainable manner.<\/li>\n<\/ul>\n\n\n\n<p id=\"7f72\">Here\u2019s a guide to some fundamental Helm commands:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"33e4\">Setup and Installation:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install Helm:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -fsSL -o get_helm.sh https:\/\/raw.githubusercontent.com\/helm\/helm\/main\/scripts\/get-helm-3 chmod 700 get_helm.sh .\/get_helm.sh<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6589\">Configuration:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add a Helm Repository:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm repo add [repo_name] [repo_url]<\/pre>\n\n\n\n<p id=\"32af\">Update Repository Information:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">helm repo update<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9397\">Deployment:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Search for Helm Charts:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm search repo [search_term]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install a Helm Chart:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm install [release_name] [repo_name]\/[chart_name]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List All Installed Helm Releases:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm list<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Get Information About a Release:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm status [release_name]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"d98a\">Updates and Rollbacks<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Upgrade an Installed Release:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm upgrade [release_name] [repo_name]\/[chart_name]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rollback a Release to a Previous Revision:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm rollback [release_name] [revision_number]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"a6fd\">Cleanup and Deletion:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Uninstall a Release:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm uninstall [release_name]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Delete a Helm Repository:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm repo remove [repo_name]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1319\">Local Chart Development<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a New Helm Chart:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm create [chart_name]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lint a Helm Chart:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm lint [chart_directory]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Package a Helm Chart:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm package [chart_directory]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"65e4\">Repositories and Plugins:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List Added Helm Repositories:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm repo list<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install a Helm Plugin:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">helm plugin install [plugin_url]<\/pre>\n\n\n\n<p id=\"8f5f\">For Helm, check out the documentation:<\/p>\n\n\n\n<p><a href=\"https:\/\/helm.sh\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/helm.sh\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Docs Home<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/helm.sh\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Everything you need to know about how the documentation is organized.<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/helm.sh\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">helm.sh<\/a><\/p>\n\n\n\n<p id=\"3dd8\">All basic commands in one go:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Initialize Helm and install Tiller (for Helm 2)<br>helm init<br><br># Helm version<br>helm version<br><br># Add a new Helm chart repository<br>helm repo add &lt;repo_name&gt; &lt;repo_url&gt;<br><br># Update Helm chart repository list<br>helm repo update<br><br># Search for Helm charts<br>helm search repo &lt;chart_name&gt;<br><br># Install a Helm chart<br>helm install &lt;release_name&gt; &lt;chart_name&gt;<br># For Helm v3 and above, use:<br>helm install &lt;release_name&gt; &lt;chart_name&gt; --generate-name<br><br># List all releases<br>helm list<br># For Helm v3 and above, you might need:<br>helm list --all-namespaces<br><br># Get information about a release<br>helm status &lt;release_name&gt;<br><br># Upgrade a release<br>helm upgrade &lt;release_name&gt; &lt;chart_name&gt;<br><br># Rollback a release to a previous revision<br>helm rollback &lt;release_name&gt; &lt;revision_number&gt;<br><br># Uninstall a release<br>helm uninstall &lt;release_name&gt;<br><br># View the values of a release<br>helm get values &lt;release_name&gt;<br><br># Lint a Helm chart<br>helm lint &lt;path_to_chart&gt;<br><br># Package a Helm chart into a versioned chart archive<br>helm package &lt;path_to_chart&gt;<br><br># View Helm history<br>helm history &lt;release_name&gt;<br><br># Create a new Helm chart<br>helm create &lt;chart_name&gt;<br><br># Render Helm chart templates locally (dry-run)<br>helm template &lt;chart_name&gt;<br><br># Pull a chart from a repository and download it to your machine<br>helm pull &lt;chart_name&gt;<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"1734\">Github Actions:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*u3BuMtj3wnJ8LIPFlt_qpA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<p id=\"5c9e\">GitHub Actions offer a powerful, integrated CI\/CD solution, allowing developers to automate, customize, and execute software development workflows directly in their GitHub repositories. For machine learning developers working with Python, it provides a seamless environment to automate tasks such as testing, building, and deploying models.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cd97\">Understanding GitHub Actions:<\/h2>\n\n\n\n<p id=\"e946\">1.&nbsp;<strong>Workflows:&nbsp;<\/strong>These are automated procedures that you can set up in your repository to build, test, package, release, or deploy any code project on GitHub.<\/p>\n\n\n\n<p id=\"e626\">2.&nbsp;<strong>Events:<\/strong>&nbsp;Workflows are triggered by events. Common events include&nbsp;<code>push<\/code>&nbsp;and&nbsp;<code>pull_request<\/code>, but there are many others, like scheduled events or manual triggers.<\/p>\n\n\n\n<p id=\"c45e\">3.&nbsp;<strong>Jobs:&nbsp;<\/strong>Jobs are a set of steps that execute on the same runner. Jobs can run in parallel, or be dependent on the success of another.<\/p>\n\n\n\n<p id=\"f862\">4.&nbsp;<strong>Steps:&nbsp;<\/strong>These are individual tasks that can run commands or actions.<\/p>\n\n\n\n<p id=\"0d55\">5.&nbsp;<strong>Actions:<\/strong>&nbsp;These are standalone commands that are combined into steps to create a job. Actions can be provided by GitHub, community-driven, or custom to your repository.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"63d0\">Setting Up a Machine Learning CI\/CD Pipeline with GitHub Actions:<\/h2>\n\n\n\n<p id=\"8f1b\"><strong>1. Create a Workflow:<\/strong>In your repository, create a directory named&nbsp;<code>.github\/workflows<\/code>. Add a new file, for instance&nbsp;<code>ml_cicd.yml<\/code>, to define your workflow.<\/p>\n\n\n\n<p id=\"df49\"><strong>2. Define Workflow Trigger:<\/strong>You can specify when your workflow should be triggered. For CI\/CD, it\u2019s common to use&nbsp;<code>push<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">on: [push]<\/pre>\n\n\n\n<p id=\"b1a0\"><strong>3. Define Jobs for Testing and Deployment:<\/strong>Set up a job to test your machine learning code every time there\u2019s a&nbsp;<code>push<\/code>&nbsp;event:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">jobs:<br>  build_and_test:<br>    runs-on: ubuntu-latest<br>    steps:<br>    - name: Checkout code<br>      uses: actions\/checkout@v2<br>    - name: Set up Python<br>      uses: actions\/setup-python@v2<br>      with:<br>        python-version: 3.8<br>    - name: Install dependencies<br>      run: |<br>        pip install -r requirements.txt<br>    - name: Run tests<br>      run: pytest<\/pre>\n\n\n\n<p id=\"570c\"><strong>4. Deploying Your Model:<\/strong>After testing, you can add steps to deploy your model:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">- name: Deploy model<br>      run: |<br>        # Your deployment script here, for example:<br>        python deploy_model.py<\/pre>\n\n\n\n<p id=\"06f8\"><strong>5. Caching and Matrix Builds:<\/strong>To speed up builds, use caching:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">- name: Cache dependencies<br>      uses: actions\/cache@v2<br>      with:<br>        path: ~\/.cache\/pip<br>        key: ${{ runner.os }}-pip-${{ hashFiles('**\/requirements.txt') }}<br>        restore-keys: |<br>          ${{ runner.os }}-pip-<\/pre>\n\n\n\n<p id=\"f2bc\">For testing across multiple Python versions, use a matrix build:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">strategy:<br>    matrix:<br>      python-version: [3.7, 3.8, 3.9]<\/pre>\n\n\n\n<p id=\"7fef\"><strong>6. Continuous Deployment:<\/strong>If you\u2019re working with cloud platforms or container orchestration systems like Kubernetes, you can incorporate steps to deploy your ML models once tests pass.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">- name: Deploy to Kubernetes<br>      run: |<br>        kubectl apply -f k8s-deployment.yaml<\/pre>\n\n\n\n<p id=\"b7cd\">Some basic actions:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Name of the workflow<br>name: CI\/CD Workflow<br><br># Event that triggers the workflow<br>on:<br>  push:<br>    branches:<br>      - main<br>  pull_request:<br>    branches:<br>      - main<br><br>jobs:<br><br>  build:<br>    name: Build Job<br>    runs-on: ubuntu-latest<br>    steps:<br>    - name: Checkout code<br>      uses: actions\/checkout@v2<br><br>    - name: Set up Python<br>      uses: actions\/setup-python@v2<br>      with:<br>        python-version: 3.8<br><br>    - name: Install dependencies<br>      run: |<br>        python -m pip install --upgrade pip<br>        pip install -r requirements.txt<br><br>    - name: Run tests<br>      run: pytest<br><br>  deploy:<br>    name: Deploy Job<br>    needs: build<br>    runs-on: ubuntu-latest<br>    steps:<br>    - name: Checkout code<br>      uses: actions\/checkout@v2<br><br>    - name: Deploy to server<br>      run: .\/deploy_script.sh<br><br>#sample file<\/pre>\n\n\n\n<p id=\"8c35\"><strong><em>Here\u2019s a list of other popular CI\/CD tools:<\/em><\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Jenkins:<\/strong>&nbsp;One of the most popular open-source automation servers, Jenkins is used for building, deploying, and automating any project. It has a vast plugin ecosystem.<\/li>\n\n\n\n<li><strong>Travis CI:<\/strong>&nbsp;Integrated with GitHub, Travis CI provides a cloud-based CI\/CD service for open source and private projects.<\/li>\n\n\n\n<li><strong>CircleCI:<\/strong>&nbsp;Offers both cloud-based and self-hosted CI\/CD solutions. Integrated with GitHub and Bitbucket.<\/li>\n\n\n\n<li><strong>GitLab CI\/CD:<\/strong>&nbsp;Part of the GitLab platform, this built-in tool offers both the repository and CI\/CD in a single service.<\/li>\n\n\n\n<li><strong>Bamboo:&nbsp;<\/strong>Atlassian\u2019s CI\/CD server solution, Bamboo integrates closely with JIRA, Bitbucket, and other Atlassian products.<\/li>\n\n\n\n<li><strong>Azure Pipelines:<\/strong>&nbsp;Part of Microsoft\u2019s Azure DevOps services, it provides CI\/CD capabilities and integrates with GitHub and external repositories.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*HLX1P4Lz-M3lrw0jslPLoA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*ujYaNWPyuatUAQDjk6POeQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"2647\">Streamlit:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*O0LLquT8n3epuBd_ld1BtQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"acc3\">Introduction to Streamlit<\/h2>\n\n\n\n<p id=\"6871\">Streamlit is an open-source app framework specifically crafted for Machine Learning and Data Science projects. With just a few lines of Python, you can swiftly turn your data scripts into interactive web applications without any need for HTML, CSS, or JavaScript knowledge. Streamlit\u2019s simple syntax and rapid development cycle make it an enticing option for data scientists looking to demonstrate their projects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"60a5\">Streamlit Installation &amp; Basic Configuration<\/h2>\n\n\n\n<p id=\"f599\">Installing Streamlit is as simple as:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install streamlit<\/pre>\n\n\n\n<p id=\"1e48\">To check that it\u2019s been installed correctly:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">streamlit hello<\/pre>\n\n\n\n<p id=\"b069\">This command launches a sample Streamlit application in your web browser.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"d516\">Building a Simple Streamlit ML App<\/h2>\n\n\n\n<p id=\"f6b2\">Let\u2019s create a machine learning model that predicts if an input text is positive or negative using the&nbsp;<code>TextBlob<\/code>&nbsp;library. We&#8217;ll then use Streamlit for interaction.<\/p>\n\n\n\n<p id=\"9440\">First, ensure you have the necessary libraries:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install streamlit textblob<\/pre>\n\n\n\n<p id=\"ca01\">Next, create a Python script (<code>app.py<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import streamlit as st<br>from textblob import TextBlob<br>st.title('Sentiment Analysis Using Streamlit')<br>user_input = st.text_area(\"Enter Text:\", \"Type Here...\")<br>if st.button(\"Analyze\"):<br>    blob = TextBlob(user_input)<br>    result = blob.sentiment.polarity<br>    if result &gt; 0:<br>        st.write(\"Positive Sentiment\")<br>    elif result &lt; 0:<br>        st.write(\"Negative Sentiment\")<br>    else:<br>        st.write(\"Neutral Sentiment\")<\/pre>\n\n\n\n<p id=\"18fd\">Run your Streamlit app:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">streamlit run app.py<\/pre>\n\n\n\n<p id=\"4bb0\">This will launch the application in your browser where you can type text and get its sentiment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"433c\">Containerizing with Docker<\/h2>\n\n\n\n<p id=\"8672\">For production deployment and consistency across platforms, you might want to containerize your Streamlit application.<\/p>\n\n\n\n<p id=\"5514\">Dockerfile for Streamlit:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM python:3.8-slim<br>WORKDIR \/app<br>COPY requirements.txt .\/requirements.txt<br>RUN pip install -r requirements.txt<br>COPY . .<br>EXPOSE 8501<br>CMD [\"streamlit\", \"run\", \"app.py\"]<\/pre>\n\n\n\n<p id=\"d866\">Here, the&nbsp;<code>requirements.txt<\/code>&nbsp;would have:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">streamlit<br>textblob<\/pre>\n\n\n\n<p id=\"b998\">Build and run the Docker container:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker build -t ml-streamlit-app:latest .<br>docker run -p 8501:8501 ml-streamlit-app:latest<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*-TKlmqUcWIyEf9CJsUFZCw.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<p id=\"c803\">All in one go:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">##########################<br>### Streamlit Commands ###<br>##########################<br><br># 1. Install Streamlit<br>pip install streamlit<br><br># 2. Create a new Streamlit script<br>echo 'import streamlit as st\\n\\nst.write(\"Hello, world!\")' &gt; app.py<br><br># 3. Run a Streamlit app<br>streamlit run app.py<br><br># 4. Secure your Streamlit app (you can set tokens, passwords, etc.)<br># Use third-party tools or services for this.<br>streamlit run app.py --secure-mode<br><br># 5. Set the Streamlit server port (e.g., to 9999)<br>streamlit run app.py --server.port 9999<br><br># 6. Disable the Streamlit welcome page<br>streamlit run app.py --server.headless true<br><br># 7. Cache data to speed up your Streamlit app<br># In your app.py script, you can use the <strong>@st<\/strong>.cache decorator for functions you want to cache.<br># Example:<br># <strong>@st<\/strong>.cache<br># def fetch_data():<br>#     return download_your_data_here()<br><br># 8. Deploying Streamlit app with Streamlit sharing<br># - First, push your app to a public GitHub repository.<br># - Then use Streamlit sharing (a service by Streamlit) to deploy directly from the repository.<br># Check the Streamlit documentation for more on this.<br><br>############################<br>### Streamlit Components ###<br>############################<br><br># Streamlit offers various components like buttons, sliders, file uploaders, etc.<br># Here are examples of a few:<br><br># In your app.py:<br><br># st.button('Click me!')<br># st.slider('Select a range', 0.0, 100.0)<br># st.file_uploader('Upload a file here')<br># st.selectbox('Choose an option', ['Option 1', 'Option 2', 'Option 3'])<br><\/pre>\n\n\n\n<p id=\"10f3\"><strong><em>Check out Streamlit tutorials:<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/docs.streamlit.io\/knowledge-base\/tutorials\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/docs.streamlit.io\/knowledge-base\/tutorials\" rel=\"noreferrer noopener\" target=\"_blank\">Tutorials &#8211; Streamlit Docs<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/docs.streamlit.io\/knowledge-base\/tutorials\" rel=\"noreferrer noopener\" target=\"_blank\">Our tutorials include step-by-step examples of building different types of apps in Streamlit.<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.streamlit.io\/knowledge-base\/tutorials\" rel=\"noreferrer noopener\" target=\"_blank\">docs.streamlit.io<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*1_8CZ326yIl2A6MsDCxlEQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"c778\">Flask:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*_61SiSQMBmyluF2gB9jK6A.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3d6a\">Flask for Machine Learning Deployment: A Beginner\u2019s Guide<\/h2>\n\n\n\n<p id=\"c417\">Table of contents:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Introduction to Flask<\/li>\n\n\n\n<li>Flask Installation &amp; Basic Configuration<\/li>\n\n\n\n<li>Building a Simple Flask ML App<\/li>\n\n\n\n<li>Containerizing with Docker<\/li>\n\n\n\n<li>Wrapping Up<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cc08\">Introduction to Flask<\/h2>\n\n\n\n<p id=\"461f\">Flask is a lightweight web server framework in Python. Its micro-framework nature makes it perfect for creating small to medium web applications quickly. It\u2019s particularly well-suited for deploying machine learning models, as it allows for flexibility and offers a direct path from your Python code to a web service.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"5192\">Flask Installation &amp; Basic Configuration<\/h2>\n\n\n\n<p id=\"657b\">Start by installing Flask using pip:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install Flask<\/pre>\n\n\n\n<p id=\"2907\">To check that it\u2019s been installed correctly, you can create a basic Flask application:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from flask import Flask<br>app = Flask(__name__)<br>@app.route('\/')<br>def hello_world():<br>    return 'Hello, World!'<\/pre>\n\n\n\n<p id=\"5d44\">Save this as&nbsp;<code>app.py<\/code>&nbsp;and run:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">export FLASK_APP=app.py<br>flask run<\/pre>\n\n\n\n<p id=\"b5ff\">This command starts your Flask app, and you should see&nbsp;<code>Hello, World!<\/code>&nbsp;when you navigate to&nbsp;<code>http:\/\/127.0.0.1:5000\/<\/code>&nbsp;in your browser.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ae4e\">Building a Simple Flask ML App<\/h2>\n\n\n\n<p id=\"2e5f\">Imagine we have a machine learning model that predicts if an input text is positive or negative using the&nbsp;<code>TextBlob<\/code>&nbsp;library. We&#8217;ll use Flask to create a simple API for this model.<\/p>\n\n\n\n<p id=\"5bdb\">First, ensure you have the necessary libraries:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install Flask textblob<\/pre>\n\n\n\n<p id=\"53a7\">Next, update&nbsp;<code>app.py<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from flask import Flask, request, jsonify<br>from textblob import TextBlob<br>app = Flask(__name__)<br>@app.route('\/analyze', methods=['POST'])<br>def analyze_sentiment():<br>    data = request.get_json()<br>    text = data['text']<br>    blob = TextBlob(text)<br>    result = blob.sentiment.polarity<br>    sentiment = \"\"<br>    if result &gt; 0:<br>        sentiment = \"Positive\"<br>    elif result &lt; 0:<br>        sentiment = \"Negative\"<br>    else:<br>        sentiment = \"Neutral\"<br>    return jsonify(sentiment=sentiment)<br>if __name__ == \"__main__\":<br>    app.run(debug=True)<\/pre>\n\n\n\n<p id=\"cc32\">This Flask app exposes a POST endpoint&nbsp;<code>\/analyze<\/code>&nbsp;that expects a JSON object with a key&nbsp;<code>text<\/code>&nbsp;and returns the sentiment of the provided text.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"01d2\">Containerizing with Docker<\/h2>\n\n\n\n<p id=\"6403\">For ease of deployment and ensuring consistency across different environments, it\u2019s useful to containerize the Flask application.<\/p>\n\n\n\n<p id=\"4b8a\">Dockerfile for Flask:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM python:3.8-slim<br>WORKDIR \/app<br>COPY requirements.txt .\/requirements.txt<br>RUN pip install -r requirements.txt<br>COPY . .<br>EXPOSE 5000<br>CMD [\"python\", \"app.py\"]<\/pre>\n\n\n\n<p id=\"8475\">Your&nbsp;<code>requirements.txt<\/code>&nbsp;should contain:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Flask<br>textblob<\/pre>\n\n\n\n<p id=\"5579\">To build and run the Docker container:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker build -t ml-flask-app:latest .<br>docker run -p 5000:5000 ml-flask-app:latest<\/pre>\n\n\n\n<p id=\"f8ec\">All in one go:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># ---- SETTING UP A VIRTUAL ENVIRONMENT AND INSTALLING FLASK ----<br># Create a virtual environment<br>python -m venv myenv<br><br># Activate the virtual environment<br># On Windows:<br>myenv\\Scripts\\activate<br># On macOS and Linux:<br>source myenv\/bin\/activate<br><br># Install Flask<br>pip install Flask<br><br># ---- BASIC FLASK APP STRUCTURE ----<br># Use this structure in your Python script (e.g., app.py)<br>\"\"\"<br>from flask import Flask<br>app = Flask(__name__)<br><br>@app.route('\/')<br>def hello_world():<br>    return 'Hello, World!'<br>\"\"\"<br><br># ---- RUNNING A FLASK APPLICATION ----<br># Set the FLASK_APP environment variable<br># On Windows:<br>set FLASK_APP=your_flask_app_filename.py<br># On macOS and Linux:<br>export FLASK_APP=your_flask_app_filename.py<br><br># Run the app<br>flask run<br><br># ---- DEVELOPMENT MODE ----<br># Activate the development environment<br># On Windows:<br>set FLASK_ENV=development<br># On macOS and Linux:<br>export FLASK_ENV=development<br><br># Now run the app<br>flask run<br><br># ---- SPECIFY HOST AND PORT ----<br>flask run --host=0.0.0.0 --port=8080<br><br># ---- USING FLASK EXTENSIONS (example: Flask-SQLAlchemy) ----<br># Install Flask-SQLAlchemy<br>pip install Flask-SQLAlchemy<br># Use in your Flask app:<br>\"\"\"<br>from flask import Flask<br>from flask_sqlalchemy import SQLAlchemy<br><br>app = Flask(__name__)<br>app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:\/\/\/your_database_name.db'<br>db = SQLAlchemy(app)<br>\"\"\"<br><br># ---- DEACTIVATE VIRTUAL ENVIRONMENT ----<br>deactivate<\/pre>\n\n\n\n<p id=\"8613\"><strong><em>Check out flask documentation:<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/flask.palletsprojects.com\/en\/2.3.x\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/flask.palletsprojects.com\/en\/2.3.x\/\" rel=\"noreferrer noopener\" target=\"_blank\">Welcome to Flask &#8211; Flask Documentation (2.3.x)<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/flask.palletsprojects.com\/en\/2.3.x\/\" rel=\"noreferrer noopener\" target=\"_blank\">Welcome to Flask&#8217;s documentation. Get started with Installation and then get an overview with the Quickstart . There is\u2026<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/flask.palletsprojects.com\/en\/2.3.x\/\" rel=\"noreferrer noopener\" target=\"_blank\">flask.palletsprojects.com<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"68ac\">Gradio:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*PBYGT-Ic1bVIrHMlcG4hjA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8949\">Introduction to Gradio<\/h2>\n\n\n\n<p id=\"0ebc\">Gradio is an open-source Python library that provides an easy way to create user-friendly web-based interfaces for machine learning models. It is designed to be straightforward, allowing ML practitioners to deploy and share their models with non-technical users quickly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"e931\">Gradio Installation &amp; Basic Configuration<\/h2>\n\n\n\n<p id=\"4682\">Installing Gradio is simple with pip:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install gradio<\/pre>\n\n\n\n<p id=\"bb11\">With Gradio installed, you can quickly create interfaces for your models without needing extensive web development expertise.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3aca\">Building a Simple Gradio ML App<\/h2>\n\n\n\n<p id=\"e188\">Let\u2019s assume we have a machine learning model that classifies handwritten digits from the MNIST dataset. We\u2019ll use Gradio to create a simple UI for this model.<\/p>\n\n\n\n<p id=\"a742\">First, ensure you have the necessary libraries:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install gradio tensorflow<\/pre>\n\n\n\n<p id=\"5bfc\">Next, build a simple model using TensorFlow and integrate it with Gradio:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import gradio as gr<br>import numpy as np<br>import tensorflow as tf<br><br># Load MNIST dataset<br>mnist = tf.keras.datasets.mnist<br>(x_train, y_train), (x_test, y_test) = mnist.load_data()<br>x_train, x_test = x_train \/ 255.0, x_test \/ 255.0  # Normalize data<br><br># Build a simple model<br>model = tf.keras.models.Sequential([<br>    tf.keras.layers.Flatten(input_shape=(28, 28)),<br>    tf.keras.layers.Dense(512, activation='relu'),<br>    tf.keras.layers.Dropout(0.2),<br>    tf.keras.layers.Dense(10)<br>])<br>model.compile(optimizer='adam',<br>              loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),<br>              metrics=['accuracy'])<br><br>model.fit(x_train, y_train, epochs=5)<br><br>def classify_digit(img):<br>    img = img.reshape(1, 28, 28)<br>    prediction = model.predict(img).tolist()[0]<br>    return {str(i): prediction[i] for i in range(10)}<br><br># Gradio UI<br>interface = gr.Interface(fn=classify_digit, <br>                         inputs=\"sketchpad\", <br>                         outputs=\"label\")<br>interface.launch()<\/pre>\n\n\n\n<p id=\"61a6\">Running this script will train the model on the MNIST dataset and then launch a Gradio interface where you can draw digits, and the model will classify them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"53a4\">Containerizing with Docker<\/h2>\n\n\n\n<p id=\"6889\">To ensure our app is consistent across various environments and to streamline deployment, it\u2019s helpful to containerize the Gradio application.<\/p>\n\n\n\n<p id=\"ee25\">Dockerfile for Gradio:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM python:3.8-slim<br>WORKDIR \/app<br>COPY requirements.txt .\/requirements.txt<br>RUN pip install --no-cache-dir -r requirements.txt<br>COPY . .<br>CMD [\"python\", \"app.py\"]<\/pre>\n\n\n\n<p id=\"7726\">Your&nbsp;<code>requirements.txt<\/code>&nbsp;should contain:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">gradio<br>tensorflow<\/pre>\n\n\n\n<p id=\"07e7\">To build and run the Docker container:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker build -t ml-gradio-app:latest .<br>docker run -p 7860:7860 ml-gradio-app:latest<\/pre>\n\n\n\n<p id=\"4ab1\">This command will launch the Gradio app in a Docker container and make it available on port 7860.<\/p>\n\n\n\n<p id=\"38e5\"><strong><em>Check out Gradio tutorials<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/www.gradio.app\/guides\/quickstart\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.gradio.app\/guides\/quickstart\" rel=\"noreferrer noopener\" target=\"_blank\">Quickstart<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/www.gradio.app\/guides\/quickstart\" rel=\"noreferrer noopener\" target=\"_blank\">A Step-by-Step Gradio Tutorial<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/www.gradio.app\/guides\/quickstart\" rel=\"noreferrer noopener\" target=\"_blank\">www.gradio.app<\/a><\/p>\n\n\n\n<p id=\"fd5b\">Also, check out the deep learning gradio course for free:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.deeplearning.ai\/short-courses\/building-generative-ai-applications-with-gradio\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.deeplearning.ai\/short-courses\/building-generative-ai-applications-with-gradio\/\" rel=\"noreferrer noopener\" target=\"_blank\">Building Generative AI Applications with Gradio<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/www.deeplearning.ai\/short-courses\/building-generative-ai-applications-with-gradio\/\" rel=\"noreferrer noopener\" target=\"_blank\">Join our new short course, Building Generative AI Applications with Gradio! Learn from Apolin\u00e1rio Passos, Machine\u2026<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/www.deeplearning.ai\/short-courses\/building-generative-ai-applications-with-gradio\/\" rel=\"noreferrer noopener\" target=\"_blank\">www.deeplearning.ai<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*gIbafC79v6O8sVJX0aPgvQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"2fa4\">FastAPI:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*xj47UqTO9j8WaZrxtHLvcA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"33ae\">Introduction to FastAPI:<\/h2>\n\n\n\n<p id=\"a4b4\">FastAPI is a modern, fast web framework for building APIs with Python, based on standard Python type hints. It offers automatic interactive API documentation, is built on top of Starlette for the web parts and Pydantic for the data parts, and is recognized for its performance, even comparable to NodeJS and Go.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8951\">Docker and Why It Matters:<\/h2>\n\n\n\n<p id=\"4a2f\">Docker allows you to package an application with all of its dependencies into a standardized unit for software development. This ensures that your application will run the same, regardless of where the Docker container runs. For ML, this is crucial as you often have numerous dependencies that can cause conflicts or versioning issues.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"e4d0\">FastAPI with Docker for ML Deployment:<\/h2>\n\n\n\n<p id=\"a18e\">FastAPI can be dockerized like any other web application. Given FastAPI\u2019s fast performance, it is well-suited to be a server for machine learning models, especially when combined with Docker\u2019s consistency and isolation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0e0b\">Hands-On Example:<\/h2>\n\n\n\n<p id=\"7209\">a. Create a FastAPI Application:<br>Let\u2019s create a simple FastAPI application to serve a machine learning model. For this guide, we\u2019ll use a pre-trained model for simplicity.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># main.py<br>from fastapi import FastAPI<br>from sklearn.datasets import load_iris<br>from sklearn.linear_model import LogisticRegression<br>app = FastAPI()<br># Load dataset and train a simple model<br>X, y = load_iris(return_X_y=True)<br>clf = LogisticRegression().fit(X, y)<br>@app.get(\"\/predict\/\")<br>def predict(sepal_length: float, sepal_width: float, petal_length: float, petal_width: float):<br>    prediction = clf.predict([[sepal_length, sepal_width, petal_length, petal_width]])<br>    return {\"prediction\": int(prediction[0])}<\/pre>\n\n\n\n<p id=\"1174\">b. Create a Dockerfile:<br>Now, let\u2019s Dockerize the FastAPI application.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Use an official Python runtime as a base image<br>FROM python:3.8-slim<br># Set the working directory<br>WORKDIR \/app<br># Install dependencies<br>COPY requirements.txt .\/<br>RUN pip install --no-cache-dir -r requirements.txt<br># Copy the current directory contents into the container at \/app<br>COPY . .<br># Expose port 8000 for FastAPI<br>EXPOSE 8000<br># Run main.py when the container launches<br>CMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>FROM python:3.8-slim<\/strong><\/code>: Use the slim version of the official Python 3.8 image as the base image for this Docker container.<\/li>\n\n\n\n<li><code><strong>WORKDIR \/app<\/strong><\/code>: Set the working directory in the container to&nbsp;<code>\/app<\/code>. All subsequent commands will be run from this directory.<\/li>\n\n\n\n<li><code><strong>COPY requirements.txt .\/<\/strong><\/code>: Copy the&nbsp;<code>requirements.txt<\/code>&nbsp;file from your host to the current location (<code>\/app<\/code>) in the container.<\/li>\n\n\n\n<li><code><strong>RUN pip install --no-cache-dir -r requirements.txt<\/strong><\/code>: Install the Python dependencies specified in&nbsp;<code>requirements.txt<\/code>&nbsp;without storing the cache, which keeps the image size smaller.<\/li>\n\n\n\n<li><code><strong>COPY . .<\/strong><\/code>: Copy all the files from the current directory on the host to the current directory (<code>\/app<\/code>) in the container.<\/li>\n\n\n\n<li><code><strong>EXPOSE 8000<\/strong><\/code>: Informs Docker that the container will listen on the specified network port at runtime, which in this case is 8000.<\/li>\n\n\n\n<li><code><strong>CMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]<\/strong><\/code>: Specifies the command that will be executed when the container starts up. Here, it&#8217;s launching the FastAPI application using Uvicorn on host&nbsp;<code>0.0.0.0<\/code>&nbsp;and port&nbsp;<code>8000<\/code>.<\/li>\n<\/ul>\n\n\n\n<p id=\"1a11\">Each instruction creates a new layer in the Docker image, and they\u2019re executed in sequence to build the final image. This Dockerfile is set up to run a FastAPI application in a containerized environment.<\/p>\n\n\n\n<p id=\"ffd0\">Your&nbsp;<code>requirements.txt<\/code>&nbsp;should have:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">fastapi<br>uvicorn<br>scikit-learn<\/pre>\n\n\n\n<p id=\"d258\">c. Build and Run with Docker:<br>With Docker installed, navigate to your project\u2019s root directory and run:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ docker build -t fastapi_ml_app .<br>$ docker run -p 8000:8000 fastapi_ml_app<\/pre>\n\n\n\n<p id=\"fb6e\">Visit&nbsp;<code>http:\/\/localhost:8000\/predict\/?sepal_length=5.1&amp;sepal_width=3.5&amp;petal_length=1.4&amp;petal_width=0.2<\/code>&nbsp;in your browser. You should see a prediction output.<\/p>\n\n\n\n<p id=\"9bae\"><strong><em>Check out FastAPI tutorials:<\/em><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/fastapi.tiangolo.com\/tutorial\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/fastapi.tiangolo.com\/tutorial\/\" rel=\"noreferrer noopener\" target=\"_blank\">Tutorial &#8211; User Guide &#8211; FastAPI<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/fastapi.tiangolo.com\/tutorial\/\" rel=\"noreferrer noopener\" target=\"_blank\">FastAPI framework, high performance, easy to learn, fast to code, ready for production<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/fastapi.tiangolo.com\/tutorial\/\" rel=\"noreferrer noopener\" target=\"_blank\">fastapi.tiangolo.com<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:2000\/1*whuRFEJE1Qvw540-RyY8Zw.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"2667\">End to End Sample project using the above tools:<\/h1>\n\n\n\n<p id=\"1dd5\">The project flow is as follows:<\/p>\n\n\n\n<p id=\"35ec\">Flow for Machine Learning Model Deployment:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"a9c4\">Develop the ML Model:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Data Collection<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Data Preprocessing<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Model Training<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Model Evaluation<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Model Export (e.g., a TensorFlow&nbsp;<\/em><\/strong><code><strong><em>SavedModel<\/em><\/strong><\/code><strong><em>&nbsp;or a PyTorch&nbsp;<\/em><\/strong><code><strong><em>state_dict<\/em><\/strong><\/code><strong><em>)<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9b4a\">Streamlit App Development:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Write the app script using Streamlit that uses the ML model for inference<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Test the app locally<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"a700\">Dockerize the Streamlit App:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Create a&nbsp;<\/em><\/strong><code><strong><em>Dockerfile<\/em><\/strong><\/code><strong><em>&nbsp;with all the necessary instructions<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Build the Docker image<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Test the Docker container locally<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ef1e\">Push to a Docker Registry:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Push the built Docker image to a container registry (e.g., Docker Hub, Google Container Registry, etc.)<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4409\">Infrastructure Setup with Terraform:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Write Terraform configurations to define and provide data center infrastructure using declarative configuration files<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Initialize Terraform, apply configurations to provision the Google Kubernetes Engine (GKE) cluster and other required resources in GCP<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3181\">Package Application with Helm:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Create a Helm chart for your Streamlit app that includes Kubernetes manifest templates and values<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Package the Helm chart<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8d0f\">Kubernetes Deployment with Helm:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Deploy your application to the Kubernetes cluster (e.g., GKE) using Helm<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Helm will use the packaged chart to deploy and manage the Kubernetes resources<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"480c\">Continuous Integration &amp; Continuous Deployment (CI\/CD):<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Use GitHub Actions to automate the model training, testing, Docker build, Terraform application, and Helm deployment<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Configure GitHub Actions workflows and triggers<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7ec6\">Monitor &amp; Scale:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><em>Monitor application and model performance using monitoring solutions (like Prometheus, Grafana)<\/em><\/strong><\/li>\n\n\n\n<li><strong><em>Scale up\/down based on traffic using Kubernetes auto-scaling or manual commands<\/em><\/strong><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"af2d\">1. Machine Learning Model:<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">import tensorflow as tf<br>import tensorflow_hub as hub<br><br>model_url = \"https:\/\/tfhub.dev\/google\/imagenet\/mobilenet_v2_100_224\/classification\/4\"<br>model = tf.keras.Sequential([<br>    hub.KerasLayer(model_url)<br>])<br><br>def classify_image(image_path):<br>    img = tf.keras.preprocessing.image.load_img(image_path, target_size=(224, 224))<br>    img_array = tf.keras.preprocessing.image.img_to_array(img)<br>    img_array = tf.expand_dims(img_array, 0) <br><br>    predictions = model.predict(img_array)<br>    top_prediction = tf.keras.applications.mobilenet_v2.decode_predictions(predictions.numpy())[0][0]<br>    return top_prediction[1], top_prediction[2]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"e4c8\">2. Streamlit App:<\/h2>\n\n\n\n<p id=\"d06e\">Python code (<code>app.py<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import streamlit as st<br>from model import classify_image<br><br>st.title(\"Image Classifier\")<br><br>uploaded_file = st.file_uploader(\"Choose an image...\", type=[\"jpg\", \"png\", \"jpeg\"])<br>if uploaded_file:<br>    st.image(uploaded_file, caption='Uploaded Image.', use_column_width=True)<br>    st.write(\"\")<br>    st.write(\"Classifying...\")<br>    label, probability = classify_image(uploaded_file)<br>    st.write(f\"Class: {label}, Confidence: {probability:.2f}%\")<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2980\">3. Docker:<\/h2>\n\n\n\n<p id=\"b788\"><strong>Dockerfile:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FROM python:3.8-slim<br><br>WORKDIR \/app<br><br>COPY requirements.txt requirements.txt<br>RUN pip install -r requirements.txt<br><br>COPY . .<br><br>CMD [\"streamlit\", \"run\", \"app.py\"]<\/pre>\n\n\n\n<p id=\"2f4a\"><code><strong>requirements.txt<\/strong><\/code><strong>:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">streamlit<br>tensorflow<br>tensorflow_hub<\/pre>\n\n\n\n<p id=\"0cc1\"><strong>Build and push to Docker Hub:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker build -t username\/image-classifier .<br>docker push username\/image-classifier<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"7553\">4. Kubernetes &amp; Helm:<\/h2>\n\n\n\n<p id=\"fa81\">Create a Helm chart for our deployment.<\/p>\n\n\n\n<p id=\"cf77\">Chart Structure (simplified):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">image-classifier-chart\/<br>|-- templates\/<br>|   |-- deployment.yaml<br>|   |-- service.yaml<br>|-- values.yaml<br>|-- Chart.yaml<\/pre>\n\n\n\n<p id=\"db04\">In&nbsp;<code>deployment.yaml<\/code>&nbsp;and&nbsp;<code>service.yaml<\/code>, define the Kubernetes deployment and service structures, referencing the Docker image and ports accordingly.<\/p>\n\n\n\n<p id=\"9c30\"><code><strong>deployment.yaml:<\/strong><\/code><\/p>\n\n\n\n<p id=\"34fa\">This file defines a Kubernetes Deployment, which ensures that a certain number of pod replicas are running at any given time.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: apps\/v1<br>kind: Deployment<br>metadata:<br>  name: image-classifier-deployment<br>spec:<br>  replicas: 2<br>  selector:<br>    matchLabels:<br>      app: image-classifier<br>  template:<br>    metadata:<br>      labels:<br>        app: image-classifier<br>    spec:<br>      containers:<br>      - name: image-classifier-container<br>        image: username\/image-classifier:latest<br>        ports:<br>        - containerPort: 8501 # Streamlit's default port<\/pre>\n\n\n\n<p id=\"b6ae\"><code><strong>service.yaml:<\/strong><\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: v1<br>kind: Service<br>metadata:<br>  name: image-classifier-service<br>spec:<br>  selector:<br>    app: image-classifier<br>  ports:<br>    - protocol: TCP<br>      port: 80<br>      targetPort: 8501<br>  type: LoadBalancer<\/pre>\n\n\n\n<p id=\"c775\"><code><strong>values.yaml:<\/strong><\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">replicaCount: 2<br><br>image:<br>  repository: username\/image-classifier<br>  tag: latest<br>  pullPolicy: IfNotPresent<br><br>service:<br>  type: LoadBalancer<br>  port: 80<\/pre>\n\n\n\n<p id=\"e380\">This is a default configuration file for Helm charts. When you deploy a Helm chart, you can override these default values.<\/p>\n\n\n\n<p id=\"791b\"><code><strong>Chart.yaml:<\/strong><\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: v2<br>name: image-classifier-chart<br>description: A Helm chart to deploy the image classifier app on Kubernetes<br>version: 0.1.0<br>appVersion: 1.0.0<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"c573\">5. GitHub Actions:<\/h2>\n\n\n\n<p id=\"8eac\">Set up a CI\/CD pipeline that builds the Docker image and pushes it to Docker Hub whenever code is committed.<\/p>\n\n\n\n<p id=\"32eb\"><code>.github\/workflows\/main.yml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">name: Build and Push Docker Image<br><br>on:<br>  push:<br>    branches:<br>      - master<br><br>jobs:<br>  build:<br>    runs-on: ubuntu-latest<br><br>    steps:<br>    - name: Checkout code<br>      uses: actions\/checkout@v2<br><br>    - name: Login to Docker Hub<br>      run: echo \"${{ secrets.DOCKER_PASSWORD }}\" | docker login -u \"${{ secrets.DOCKER_USERNAME }}\" --password-stdin<br><br>    - name: Build and Push Docker Image<br>      run: |<br>        docker build -t username\/image-classifier .<br>        docker push username\/image-classifier<\/pre>\n\n\n\n<p id=\"9a00\">Once the GitHub Action successfully builds and pushes the Docker image, you can use Helm to deploy the chart to a Kubernetes cluster.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"d3f4\">Deploying with Helm:<\/h2>\n\n\n\n<p id=\"ad1e\">To deploy the Streamlit app using Helm:<\/p>\n\n\n\n<p id=\"7b11\">Package the Helm chart:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">helm package image-classifier-chart<\/pre>\n\n\n\n<p id=\"276e\">Install the chart onto your Kubernetes cluster:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">helm install image-classifier-release image-classifier-chart-0.1.0.tgz<\/pre>\n\n\n\n<p id=\"3bea\">Once the deployment is complete, you\u2019ll get an external IP address from the LoadBalancer. Accessing this IP on a browser will take you to the Streamlit app.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"119f\">Additonal Tools:Terraform(IAC):<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*la30PkayqhKuId6JTtToEA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ed66\">Introduction to Terraform:<\/h2>\n\n\n\n<p id=\"0a4e\">Terraform is an open-source infrastructure-as-code (IAC) software tool developed by HashiCorp. It allows users to define and provision data center infrastructure using a declarative configuration language. With Terraform, you can manage and automate infrastructure across multiple cloud providers, making it an essential tool for modern cloud-based applications, including ML deployments.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6f43\">Why Terraform for ML Deployment?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Immutable Infrastructure: Define your ML infrastructure once and deploy consistently across stages.<\/li>\n\n\n\n<li>Provider Agnostic: Whether you use AWS, Google Cloud, Azure, or a combination, Terraform has got you covered.<\/li>\n\n\n\n<li>Scalability: Easily scale ML resources up or down based on demand.<\/li>\n\n\n\n<li>Version Controlled: Infrastructure is stored as code, making versioning and rollbacks seamless.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cdef\">Setting Up Terraform for ML Environments<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install Terraform: Follow the official installation guide tailored for your OS.<\/li>\n\n\n\n<li>Initialize a New Terraform Configuration: Use&nbsp;<code>terraform init<\/code>&nbsp;to begin a new project.<\/li>\n\n\n\n<li>Configure Cloud Provider: Set up authentication for your chosen cloud provider(s).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"29e6\">Deploying ML Infrastructure using Terraform<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Define Infrastructure: Describe resources like VMs, storage, and networking required for your ML model in a&nbsp;<code>.tf<\/code>&nbsp;file.<\/li>\n\n\n\n<li>Plan the Deployment: Using&nbsp;<code>terraform plan<\/code>, review changes before they are applied.<\/li>\n\n\n\n<li>Apply the Changes:&nbsp;<code>terraform apply<\/code>&nbsp;will provision the defined resources.<\/li>\n\n\n\n<li>Integrate ML Components: Once infrastructure is ready, deploy your ML model, necessary services, and other components.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"f8bf\">Continuous Integration and Continuous Deployment (CI\/CD) with Terraform<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Automate Workflow: Integrate Terraform with CI\/CD tools like Jenkins, GitHub Actions, or GitLab CI.<\/li>\n\n\n\n<li>Automated Testing: Ensure the integrity of your ML deployment by automating infrastructure testing.<\/li>\n\n\n\n<li>Rollback Capabilities: With version-controlled infrastructure, rollbacks are smoother and more manageable.<\/li>\n\n\n\n<li>Collaborate: Use Terraform Cloud or Terraform Enterprise for collaboration features and remote state management.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"eb61\">Best Practices and Tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Modularize Configurations: Break down configurations into modules for better organization and reusability.<\/li>\n\n\n\n<li>Secure Sensitive Data: Use secrets management tools and avoid hardcoding credentials.<\/li>\n\n\n\n<li>Regularly Update: Ensure you\u2019re always using the latest version of Terraform and provider plugins.<\/li>\n\n\n\n<li>Document: Just as with code, commenting and documenting your Terraform configurations is crucial.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"82cb\">Initialization:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Initialize a New Terraform Working Directory:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform init<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This command is used to initialize a working directory containing Terraform configuration files. It\u2019s the first command that should be run after writing a new Terraform configuration.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"01e2\">Managing Infrastructure<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Plan and Preview Infrastructure Changes:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform plan<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This command lets you see what changes Terraform will apply to your infrastructure before it actually does anything.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"87e5\">Apply Infrastructure Changes:<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform apply<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This command applies the changes required to reach the desired state defined in your configuration.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"dd66\">Destroy Infrastructure<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform destroy<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Removes all resources created by your Terraform configuration. Be cautious with this command; it will literally tear down everything described in the Terraform configuration.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0410\">Inspecting State<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Show Current State:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform show<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Provides a readable version of the current infrastructure state.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"13cb\">Managing Modules:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Get Modules:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform get<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Downloads and installs modules needed for the current configuration.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bf00\">Workspace Management<\/h2>\n\n\n\n<p id=\"e06c\">Workspaces allow you to maintain multiple distinct states for the same configuration.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>List Workspaces:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform workspace list<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Select Workspace:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform workspace select [workspace_name]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create New Workspace:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform workspace new [workspace_name]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fe44\">Formatting and Validation:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Format Configuration:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform fmt<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This command is used to rewrite Terraform configuration files in a canonical format and style.<\/li>\n\n\n\n<li>Validate Configuration:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform validate<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Validates the configuration files in a directory, referring only to the configuration and not accessing any remote services like providers.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9dc7\">Importing Existing Infrastructure<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Import Resources:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform import [address] [resource_id]<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Imports existing infrastructure into your Terraform state. Useful for getting pre-existing infrastructure managed under Terraform.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8beb\">Output Values:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Show Outputs:<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">terraform output<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Displays the output values from your last&nbsp;<code>apply<\/code>.<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"0e5c\">Notes:<\/h1>\n\n\n\n<p id=\"c178\">Remember, Terraform configurations are written in files with the&nbsp;<code>.tf<\/code>&nbsp;extension. When running commands like&nbsp;<code>plan<\/code>&nbsp;and&nbsp;<code>apply<\/code>, Terraform uses the configuration files in the current directory.<\/p>\n\n\n\n<p id=\"5366\">Check out my article about terraform if you want to learn more.<\/p>\n\n\n\n<p><a href=\"https:\/\/betterprogramming.pub\/a-comprehensive-guide-to-mlops-infrastructure-as-code-iac-ef4c97742351\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/betterprogramming.pub\/a-comprehensive-guide-to-mlops-infrastructure-as-code-iac-ef4c97742351\" rel=\"noreferrer noopener\" target=\"_blank\">A Comprehensive Guide to MLOps: Infrastructure As Code(IaC)<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/betterprogramming.pub\/a-comprehensive-guide-to-mlops-infrastructure-as-code-iac-ef4c97742351\" rel=\"noreferrer noopener\" target=\"_blank\">GCP provisioning using Terraform<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/betterprogramming.pub\/a-comprehensive-guide-to-mlops-infrastructure-as-code-iac-ef4c97742351\" rel=\"noreferrer noopener\" target=\"_blank\">betterprogramming.pub<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"3f0b\">Spinnaker:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*k99RX0Yyz61jwN0R_dWd2A.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<p id=\"7c17\">Spinnaker is an open-source, multi-cloud continuous delivery platform that helps developers automate, manage, and monitor the deployment of applications. It was created by Netflix and is now backed by Google, making it a reliable choice for modern software delivery.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6a62\">Why Spinnaker for ML?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Scalability:<\/strong>&nbsp;With ML models becoming increasingly complex and resource-demanding, Spinnaker\u2019s cloud-native approach ensures seamless scaling.<\/li>\n\n\n\n<li><strong>Versioning:<\/strong>&nbsp;ML models often need frequent updates. Spinnaker allows for smooth versioning of deployed models.<\/li>\n\n\n\n<li><strong>Rollbacks:<\/strong>&nbsp;In case an ML model doesn\u2019t perform as expected, Spinnaker provides easy rollback options.<\/li>\n\n\n\n<li><strong>Multi-cloud:<\/strong>&nbsp;If your ML deployments need to leverage resources from multiple cloud providers, Spinnaker has you covered.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"81b3\">Deploying an ML model using Spinnaker<\/h2>\n\n\n\n<p id=\"672d\">Here\u2019s a simplified process to get you started:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Package your ML model:<\/strong>&nbsp;Your model, pre-trained weights, and inference code should be containerized using tools like Docker.<\/li>\n\n\n\n<li><strong>Integrate with CI tools:<\/strong>&nbsp;Ensure your model containers are built automatically using CI tools like Jenkins or Travis CI.<\/li>\n\n\n\n<li><strong>Create a Spinnaker Application:<\/strong>&nbsp;This is a logical grouping for your deployment pipelines.<\/li>\n\n\n\n<li><strong>Define a Deployment Pipeline:&nbsp;<\/strong>Define stages like \u2018Fetch the latest model\u2019, \u2018Deploy to staging\u2019, \u2018Run tests\u2019, and \u2018Deploy to production\u2019.<\/li>\n\n\n\n<li><strong>Automate:&nbsp;<\/strong>Trigger the deployment pipeline automatically every time there\u2019s an update to your ML model.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6ca0\">Continuous delivery in ML with Spinnaker<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Automate Model Testing:<\/strong>&nbsp;Integrate model validation tests in your deployment pipeline.<\/li>\n\n\n\n<li><strong>Blue\/Green Deployments:<\/strong>&nbsp;Deploy new versions alongside the old, directing a subset of traffic to the new version. Useful for A\/B testing of models.<\/li>\n\n\n\n<li><strong>Monitoring &amp; Logging:<\/strong>&nbsp;Integrate with monitoring tools like Prometheus and Grafana to keep an eye on model performance and resource utilization.<\/li>\n\n\n\n<li><strong>Feedback Loop:&nbsp;<\/strong>Quickly iterate on model updates based on real-world feedback and performance metrics.<\/li>\n<\/ul>\n\n\n\n<p id=\"83e6\">Some basic commands:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">##########################<br>### Spinnaker Commands ###<br>##########################<br><br># 1. Install `hal` (Halyard), the command-line tool for configuring and managing Spinnaker<br>curl -O https:\/\/raw.githubusercontent.com\/spinnaker\/halyard\/master\/install\/debian\/InstallHalyard.sh<br>sudo bash InstallHalyard.sh<br>sudo update-hal<br><br># 2. Choose cloud providers (e.g., AWS, GCP, Kubernetes)<br>hal config provider [provider name] enable<br><br># 3. For Kubernetes (as an example cloud provider)<br># Assuming you have a kubeconfig file already set up<br>hal config provider kubernetes account add my-k8s-account --provider-version v2 \\<br>    --kubeconfig-file ~\/.kube\/config<br><br># 4. Set the deployment environment<br>hal config deploy edit --type distributed --account-name my-k8s-account<br><br># 5. Choose storage for Spinnaker's persistent data <br># Example with GCS (Google Cloud Storage)<br>hal config storage gcs edit --project [YOUR_PROJECT_ID] --bucket-location [BUCKET_LOCATION] --json-path [PATH_TO_SERVICE_ACCOUNT_JSON]<br>hal config storage edit --type gcs<br><br># 6. Choose the version of Spinnaker you want to run<br>hal version list<br>hal config version edit --version [desired version]<br><br># 7. Deploy Spinnaker using Halyard<br>hal deploy apply<br><br># 8. Connect to the Spinnaker UI <br># Assuming you are using Kubernetes, set up port forwarding:<br>kubectl port-forward -n spinnaker svc\/spin-deck 9000:9000 &amp; kubectl port-forward -n spinnaker svc\/spin-gate 8084:8084<br><br># Now, you can access Spinnaker at http:\/\/localhost:9000<br><br># 9. Update Spinnaker (after choosing a new version with `hal version edit`)<br>hal deploy apply<br><br># 10. Backup Halyard's configuration<br>tar -czf hal-backup.tgz ~\/.hal\/<\/pre>\n\n\n\n<p id=\"3eb5\">Check out the documentation<\/p>\n\n\n\n<p><a href=\"https:\/\/spinnaker.io\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/spinnaker.io\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Documentation<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/spinnaker.io\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Multi-cloud continuous delivery for the enterprise<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/spinnaker.io\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">spinnaker.io<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"e853\">Crossplane:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*52ORsiWUE6CXjbb6xpp2ZQ.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<p id=\"db84\">Crossplane is an open-source infrastructure-as-code (IAC) platform that extends Kubernetes to include cloud infrastructure orchestration. It integrates directly with Kubernetes, allowing you to declare, automate, and manage external infrastructure using familiar K8s tools and practices.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1160\">Crossplane\u2019s Role in ML Deployment:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Unified Workflow:&nbsp;<\/strong>With Crossplane, manage both Kubernetes-native and cloud-native resources using&nbsp;<code>kubectl<\/code>.<\/li>\n\n\n\n<li><strong>Provider Diversity:&nbsp;<\/strong>Support for multiple cloud providers ensures that ML deployments can be provider-agnostic.<\/li>\n\n\n\n<li><strong>Dynamic Scaling:<\/strong>&nbsp;ML resources can be scaled based on demand, fully automated.<\/li>\n\n\n\n<li><strong>Secure Configuration:<\/strong>&nbsp;Manage sensitive configuration and secrets seamlessly.<\/li>\n<\/ul>\n\n\n\n<p id=\"61a4\">Check out cross-plane documentation:<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.crossplane.io\/v1.13\/getting-started\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/docs.crossplane.io\/v1.13\/getting-started\/\" rel=\"noreferrer noopener\" target=\"_blank\">Crossplane Docs \u00b7 v1.13 \u00b7 Getting Started<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/docs.crossplane.io\/v1.13\/getting-started\/\" rel=\"noreferrer noopener\" target=\"_blank\">Hands-On Want a hands-on example? Follow a Crossplane Quickstart for your cloud provider. AWS quickstart Azure\u2026<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/docs.crossplane.io\/v1.13\/getting-started\/\" rel=\"noreferrer noopener\" target=\"_blank\">docs.crossplane.io<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"4fc8\">Puppet:<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*1elqyivF5Tk2B7SlgLVJiA.png\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Image by the Author<\/figcaption><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Configuration Management Tool:<\/strong>&nbsp;Puppet is a configuration management tool that automates the provisioning and management of servers.<\/li>\n\n\n\n<li><strong>Declarative Language:<\/strong>&nbsp;Users define the desired state of the infrastructure (what you want the system to look like, what software packages it should have, etc.) using Puppet\u2019s declarative language, and Puppet will enforce this desired state.<\/li>\n\n\n\n<li><strong>Infrastructure as Code:&nbsp;<\/strong>With Puppet, infrastructure is managed as code. This allows for versioning, peer review, and automated testing, just like any other software codebase.<\/li>\n\n\n\n<li><strong>Idempotency:&nbsp;<\/strong>One of the key features of Puppet is its idempotent nature \u2014 which means it ensures that the end state remains consistent with each run, irrespective of the initial conditions. If the desired state is already met, Puppet won\u2019t make any changes.<\/li>\n\n\n\n<li><strong>Agent\/Server Model:<\/strong>&nbsp;Typically, Puppet follows a master-agent setup. The master contains the configurations defined by Puppet code, and agents periodically check in with the master to fetch configuration instructions.<\/li>\n\n\n\n<li><strong>Modules and Forge:&nbsp;<\/strong>Modules are reusable, shareable chunks of code that perform specific tasks in Puppet. Puppet Forge is a marketplace where community members can share these modules.<\/li>\n\n\n\n<li><strong>Flexibility:&nbsp;<\/strong>Puppet can manage a diverse range of infrastructure, from bare metal to containers, and across different platforms and cloud environments.<\/li>\n\n\n\n<li><strong>Reporting:<\/strong>&nbsp;Puppet provides detailed reports that show what changes have been made and who made them.<\/li>\n\n\n\n<li><strong>Integrations:<\/strong>&nbsp;Puppet integrates well with other DevOps tools, enabling users to build complete Continuous Integration\/Continuous Deployment (CI\/CD) pipelines.<\/li>\n\n\n\n<li><strong>Open Source and Enterprise Versions:<\/strong>&nbsp;Puppet is available in both open source and enterprise versions. The enterprise version provides additional features, including a graphical interface, analytics, and professional support.<\/li>\n<\/ul>\n\n\n\n<p id=\"45a4\">Check out puppet documentation:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.puppet.com\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.puppet.com\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Docs | Puppet<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/www.puppet.com\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Explore Puppet Product Documentation. Puppet automates away the challenges, complexity, and risk of securing and\u2026<\/a><\/h3>\n\n\n\n<p><a href=\"https:\/\/www.puppet.com\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">www.puppet.com<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"3666\">Conclusion:<\/h1>\n\n\n\n<p id=\"1653\">Deploying machine learning models seamlessly and efficiently requires a holistic approach, combining the power of various tools tailored for different tasks. From crafting interactive front-end applications using Streamlit, Gradio, Flask, or FastAPI to containerizing with Docker, orchestrating with Kubernetes and Helm, and automating infrastructure with Terraform, the contemporary ML deployment landscape is rich and diverse. Leveraging these tools not only ensures robust and scalable deployments but also accelerates the journey from model development to real-world impact. As the tech ecosystem evolves, these integrated tools pave the way for an era of streamlined ML deployments.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"a595\">References:<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Docker:<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/docs.docker.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">Docker official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cDocker Up &amp; Running\u201d by Karl Matthias and Sean P. Kane.<\/li>\n<\/ul>\n\n\n\n<p id=\"d79a\">2.&nbsp;<strong>Kubernetes:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/kubernetes.io\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Kubernetes official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cKubernetes: Up and Running\u201d by Kelsey Hightower, Brendan Burns, and Joe Beda.<\/li>\n<\/ul>\n\n\n\n<p id=\"c389\">3.&nbsp;<strong>Helm:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/helm.sh\/docs\/\" rel=\"noreferrer noopener\" target=\"_blank\">Helm official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cHelm 3 Cookbook\u201d by Sabin Manelius and Steven Wedig.<\/li>\n<\/ul>\n\n\n\n<p id=\"84bb\">4.&nbsp;<strong>Streamlit:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/docs.streamlit.io\/\" rel=\"noreferrer noopener\" target=\"_blank\">Streamlit official documentation<\/a><\/li>\n\n\n\n<li>Book: Due to Streamlit being relatively new, there aren\u2019t many dedicated books as of my last update in 2021. However, online blogs, tutorials, and the official documentation should suffice.<\/li>\n<\/ul>\n\n\n\n<p id=\"da6f\"><strong>5. Gradio:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/gradio.app\/docs\" rel=\"noreferrer noopener\" target=\"_blank\">Gradio official documentation<\/a><\/li>\n\n\n\n<li>Gradio is a newer tool and might not have dedicated books. The official documentation and online resources can be the best guide.<\/li>\n<\/ul>\n\n\n\n<p id=\"3d12\"><strong>6. Flask:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/flask.palletsprojects.com\/en\/2.0.x\/\" rel=\"noreferrer noopener\" target=\"_blank\">Flask official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cFlask Web Development\u201d by Miguel Grinberg.<\/li>\n<\/ul>\n\n\n\n<p id=\"34bd\"><strong>7. FastAPI:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/fastapi.tiangolo.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">FastAPI official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cFastAPI By Example\u201d by Michael Herman.<\/li>\n<\/ul>\n\n\n\n<p id=\"c284\"><strong>8. Terraform:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/index.html\" rel=\"noreferrer noopener\" target=\"_blank\">Terraform official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cTerraform: Up &amp; Running\u201d by Yevgeniy Brikman.<\/li>\n<\/ul>\n\n\n\n<p id=\"69d8\"><strong>9. GitHub Actions:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Documentation:&nbsp;<a href=\"https:\/\/docs.github.com\/en\/actions\" rel=\"noreferrer noopener\" target=\"_blank\">GitHub Actions official documentation<\/a><\/li>\n\n\n\n<li>Book: \u201cGitHub Actions for Developers\u201d by Neha Soni.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Streamlit, Gradio, FastAPI, Flask, Terraform, Spinnaker, Puppet Introduction: In the dynamic world of machine learning, the journey from developing a model to putting it into production is often seen as&#8230; <a class=\"read-more-link\" href=\"https:\/\/tbekk.com\/devstream\/2023\/08\/14\/mlops-mastering-machine-learning-deployment-an-intro-to-docker-kubernetes-helm-and-modern-web-frameworks-end-to-end-project\/\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[51,158],"tags":[258,282,240,281,283,284,285,278,279,280],"class_list":["post-818","post","type-post","status-publish","format-standard","hentry","category-article","category-mlops","tag-docker","tag-fastapi","tag-flask","tag-github-actions","tag-gradio","tag-helm","tag-kubernetes","tag-model-deployment","tag-streamlit","tag-terraform"],"_links":{"self":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts\/818","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/comments?post=818"}],"version-history":[{"count":1,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts\/818\/revisions"}],"predecessor-version":[{"id":819,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts\/818\/revisions\/819"}],"wp:attachment":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/media?parent=818"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/categories?post=818"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/tags?post=818"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}