<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Louis-Alexandre LAGUET</title>
    <description>The latest articles on DEV Community by Louis-Alexandre LAGUET (@louisalexandrelaguet).</description>
    <link>https://dev.to/louisalexandrelaguet</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1441908%2F64f5bfb1-493d-48f6-ad89-05d2906eaf58.jpg</url>
      <title>DEV Community: Louis-Alexandre LAGUET</title>
      <link>https://dev.to/louisalexandrelaguet</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/louisalexandrelaguet"/>
    <language>en</language>
    <item>
      <title>How to Deploy a Fast API Application to a Kubernetes Cluster using Podman and Minikube</title>
      <dc:creator>Louis-Alexandre LAGUET</dc:creator>
      <pubDate>Mon, 22 Apr 2024 13:39:03 +0000</pubDate>
      <link>https://dev.to/louisalexandrelaguet/how-to-deploy-a-fast-api-application-to-a-kubernetes-cluster-using-podman-and-minikube-168e</link>
      <guid>https://dev.to/louisalexandrelaguet/how-to-deploy-a-fast-api-application-to-a-kubernetes-cluster-using-podman-and-minikube-168e</guid>
      <description>&lt;p&gt;This tutorial is designed to guide you through deploying a FastAPI application to a Kubernetes cluster using Podman and Minikube. I developed this guide with insights from &lt;a class="mentioned-user" href="https://dev.to/bravinsimiyu"&gt;@bravinsimiyu&lt;/a&gt; and his tutorial, which is listed in the sources section at the end of this document.&lt;/p&gt;



&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.python.org/downloads/"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://podman.io/docs/installation"&gt;Podman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://minikube.sigs.k8s.io/docs/start/"&gt;MiniKube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/"&gt;Kubernetes CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fastapi.tiangolo.com/"&gt;FastAPI&lt;/a&gt; &amp;amp; &lt;a href="https://www.uvicorn.org/"&gt;Uvicorn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  Write some code
&lt;/h2&gt;

&lt;p&gt;Through this tutorial, we will be using this simple code in a file named 'main.py':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Running the FastAPI application using Uvicorn
&lt;/h2&gt;

&lt;p&gt;To run your FastAPI application, use the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command starts your application and makes it accessible at &lt;a href="http://127.0.0.1:8000"&gt;http://127.0.0.1:8000&lt;/a&gt;.&lt;br&gt;
&lt;em&gt;NOTE: In the command 'uvicorn main:app', 'main' refers to the name of your Python file (without the .py extension), and 'app' is the name of the FastAPI instance created in your code.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Running the FastAPI application using Podman
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Create a requirements.txt file
&lt;/h3&gt;

&lt;p&gt;A 'requirements.txt' file contains the framework and the dependencies for the FastAPI application. Podman will install all these requirements when creating a podman image for the FastAPI application.&lt;br&gt;
Create a new file named 'requirements.txt'. Open the file and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastapi
uvicorn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Write a Dockerfile for the FastAPI application
&lt;/h3&gt;

&lt;p&gt;A Dockerfile is an executable file that contains a list of commands or instructions for creating a podman image. Podman Engine will execute all these commands in chronological order and create a podman image.&lt;br&gt;
Create a new file named 'Dockerfile'. Open the file and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;#Instruct Podman Engine to use official python:3.12 as the base image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.12&lt;/span&gt;

&lt;span class="c"&gt;#Create a working directory(app) for the Podman image and container&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;#Copy the framework and the dependencies of the FastAPI application into the working directory&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;

&lt;span class="c"&gt;#Install the framework and the dependencies in the requirements.txt file in our Podman image and container&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;#Copy the remaining files and the source code from the host fast-api folder to the FastAPI application container working directory&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;#Expose the FastAPI application on port 8000 inside the container&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8000&lt;/span&gt;

&lt;span class="c"&gt;#Start and run the FastAPI application container&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["uvicorn", "main:app", "--host", "0.0.0.0"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build a podman image for the FastAPI application using the Dockerfile
&lt;/h3&gt;

&lt;p&gt;We will build the podman image for the FastAPI application using the instructions in the Dockerfile. &lt;br&gt;
Run this podman command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;podman build &lt;span class="nt"&gt;-t&lt;/span&gt; docker.io/louisalexandrelaguet/fast-api &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: Ensure you name the podman image using your Docker Hub account username. It will make it easier to push the podman image to the Docker Hub repository.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Run a podman container using the podman image
&lt;/h3&gt;

&lt;p&gt;We will run a podman container using the podman image. When you run a podman image, it will run a podman container for the application. In your terminal, run this podman command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;podman run &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 docker.io/louisalexandrelaguet/fast-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will start your application and it will be reachable at &lt;a href="http://127.0.0.1:8000"&gt;http://127.0.0.1:8000&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Running the FastAPI application using Minikube
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Push your podman image to the Docker Hub
&lt;/h3&gt;

&lt;p&gt;You must push the image you created previously to the Docker Hub so that the deployment in your cluster can pull it and run it inside a pod. You can do that by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;podman push docker.io/louisalexandrelaguet/fast-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Kubernetes YAML file
&lt;/h3&gt;

&lt;p&gt;The Kubernetes YAML file describes the resources for the Kubernetes application and pods that will be created in the Kubernetes Cluster. This file also configures the Kubernetes Service for the application. Kubectl will use this file to deploy the Dockerized Fast API application to Minikube. &lt;br&gt;
Create a new file named 'kubernetes.yaml'. Open the file and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast-api-deployment&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast-api&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast-api&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast-api&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker.io/louisalexandrelaguet/fast-api&lt;/span&gt;
        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;256Mi"&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8000&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast-api-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast-api&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8000&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8000&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 'kubernetes.yaml' is divided into two. The first part is known as Deployment while the second is known as Service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment:&lt;/strong&gt; The first part of the file will configure the application pods and the resources of your deployed application. It will create two pods. Pods are replicas or instances of the deployed application. It will use your image to create the Podman Container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service:&lt;/strong&gt; This second type of file configures the Kubernetes Service for the application. It uses the LoadBalancer Kubernetes Service to equally distribute traffic to the two container pods. Minikube will assign an External IP address to the Kubernetes Service. It will enable us to access the deployed Fast API application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start MiniKube
&lt;/h3&gt;

&lt;p&gt;Open a terminal as an administrator and run the following command to start Minikube:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;minikube start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Minikube is running, you can create the deployment and the service that will run your podman image by calling the 'kubectl' command on your 'kubernetes.yaml' file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; kubernetes.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Accessing the Deployed FastAPI application
&lt;/h3&gt;

&lt;p&gt;To access the deployed FastAPI application, Minikube will assign an External IP address to the &lt;em&gt;fast-api-service&lt;/em&gt;. You will type the External IP address in your web browser and access the application. To get the External IP address, run this minikube command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;minikube service fast-api-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply type the assigned IP address in your web browser to access your deployed FastAPI application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stop the deployment
&lt;/h3&gt;

&lt;p&gt;To stop the deployment of your FastAPI application, you must delete the deployment and the service you created with the commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete deployment.apps/fast-api-deployment
kubectl delete service/fast-api-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, if you want to stop Minikube, simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;minikube stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/bravinsimiyu/how-to-dockerize-and-deploy-a-fast-api-application-to-kubernetes-cluster-35a9"&gt;How to Dockerize and Deploy a Fast API Application to Kubernetes Cluster&lt;/a&gt; from &lt;a class="mentioned-user" href="https://dev.to/bravinsimiyu"&gt;@bravinsimiyu&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>python</category>
      <category>minikube</category>
      <category>podman</category>
    </item>
  </channel>
</rss>
