How to Dockerize and Deploy a Fast API Application to Kubernetes Cluster
Tags: devops, docker, python, kubernetes
Published: 2023-07-11 11:59:18

[Docker](https://www.docker.com/) is one of the most powerful and popular containerization tools that leverage OS virtualization. It creates Docker Containers which run in an isolated environment from the original application. Docker containers contain all the configuration and files to run an application. They can easily be shared among different developers when they are hosted in the [Docker Hub](https://hub.docker.com/) registry.

In this tutorial, you will learn how to Dockerize and Deploy a [Fast API](https://fastapi.tiangolo.com/) application to Kubernetes. We will first create and run a Fast API application locally. We will Dockerize the Fast API application and run it as a Docker container. We will finally deploy the Dockerized Fast API application to Kubernetes.

[Kubernetes](https://kubernetes.io/) is an open-source platform that automatically manages the deployment of Docker containers. Kubernetes orchestrates application containers and hosts them in a Kubernetes cluster. A Kubernetes Cluster has nodes (Master and worker nodes) that run and manage the hosted/deployed container applications. The deployed containers run in a Kubernetes environment known as pods. A pod is the smallest deployable unit that runs in a Kubernetes cluster. 

In this tutorial, we will deploy the Dockerized Fast API application to a local Kubernetes Cluster known as [Minikube](https://minikube.sigs.k8s.io/docs/start/). We will talk more about Minikube later. Let's start working on our project!

### Prerequisites
For you to easily follow along with this tutorial and deploy your application to Kubernetes, you need to understand [Docker](https://docs.docker.com/get-docker/). You must also have the following software on your computer:

- [VS Code](https://code.visualstudio.com/) code editor
- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
- [Python Pip](https://pypi.org/project/pip/) package manager
- [Python ≥v3.7](https://www.python.org/)

### Getting started with Fast API
FastAPI is a popular Python Web framework that developers use to create RESTful APIs. It is based on Pydantic and Python-type hints that assist in the serialization, deserialization, and validation of data. In this tutorial, we will use FastAPI to create a simple "Hello World" application. We test and run the application locally. FastAPI requires a [ASGI server](https://asgi.readthedocs.io/en/latest/) to run the application production such as [Uvicorn](https://www.uvicorn.org/). 

As with any application or project we need to install the framework and the dependencies. Let's install the Fast API framework and Uvicorn using the following `pip` commands:

```pip
pip install fastapi
pip install "uvicorn[standard]"
```
After the installation process, create a new folder named `fast-api` and open it with VS Code. In the folder, create a new file named `main.py` and add the following Python code:

```python
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}
```
The Python snippet above will create a `route` route that will return "Hello": "World". To run the application, `cd` into the `fast-api` folder and execute this `uvicorn` command in your terminal:

```uvicorn
uvicorn main:app
```
The command will start your application on http://127.0.0.1:8000 as shown below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yg3wck5i81h85ooek5xt.png)

You can then type the URL above in your web browser to view the application:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcxhpsw64cus1jp2kfrq.png)

Our FastAPI application is running, the next step is to Dockerize the FastAPI application.

### Dockerizing the FastAPI application
We will run the FastAPI application inside a Docker Container. To Dockerize the FastAPI application, we need to follow these steps:

1. Create a `requirements.txt` file.
2. Write a Dockerfile for the FastAPI application.
3. Build a Docker Image for the FastAPI application using the Dockerfile.
4. Launch a Docker Container using the Docker Image.

Let's apply these steps.

#### Create a `requirements.txt` file
A `requirements.txt` file contains the framework and the dependencies for the FastAPI application. Docker will install all these requirements when creating a Docker image for the FastAPI application.

In the `fast-api` folder, create a new file named `requirements.txt`. Open the file and add the following:

```txt
fastapi
uvicorn
```
#### Write a Dockerfile for the FastAPI application
Dockerfile is an executable file that contains a list of commands or instructions for creating a Docker Image. Docker Engine will execute all these commands in chronological order and create a Docker image. In the `fast-api` folder, create a new file named `requirements.txt`. Open the file and add the following:

```docker
#It instructs Docker Engine to use official python:3.10 as the base image
FROM python:3.10

#It creates a working directory(app) for the Docker image and container
WORKDIR /app

#It copies the framework and the dependencies for the FastAPI application into the working directory
COPY requirements.txt .

#It will install the framework and the dependencies in the `requirements.txt` file in our Docker image and container.
RUN pip install -r requirements.txt

#It will copy the remaining files and the source code from the host `fast-api` folder to the `app` container working directory
COPY . .

#It will expose the FastAPI application on port `8000` inside the container
EXPOSE 8000

#It is the command that will start and run the FastAPI application container
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]
```
### Build a Docker Image for the FastAPI application using the Dockerfile
We will build the Docker Image for the FastAPI application using the instructions in the Dockerfile. You will `cd` into the `fast-api` folder in your terminal and run this `docker` command:

```docker
docker build -t bravinwasike/fast-api .
```
NOTE: Ensure you name the Docker image using your Docker Hub account user name. It will make it easier to push the Docker Image to the Docker Hub repository. The command will display the following output in your terminal:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hlibl397tc73144dbko.png)

#### Launch a Docker Container using the Docker Image
We will launch a Docker Container using the Docker Image. When you run a Docker Image, it will launch a Docker Container for the application. In your terminal, run this `docker` command:

```docker
docker run -p 8000:8000 bravinwasike/fast-api
```
The command will start your application on http://127.0.0.1:8000 as shown below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rasp1id8xeiyu1b6650l.png)

You can then type the URL above in your web browser to view the application:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/er4cis7ub62d6m7q9kvb.png)

We have Dockerized the Fast API application. Let's push the Docker Image to Docker Hub.

### Pushing the Docker Image to Docker Hub
To push the Docker Image to Docker Hub you need to login into your Docker Hub account from your terminal:

```docker
docker login
```
You will then push the Docker image using the following `docker` command:

```docker
docker push bravinwasike/fast-api
```
You must push the Docker Image that you have created to Docker Hub. We will use this Docker Image when deploying the Fast API application to Minikube. Let's get started with Minikube.

### Getting started with Minikube
Minikube is a Kubernetes engine that allows DevOps engineers to create a Kubernetes cluster on their local machines. The Minikube Kubernetes Cluster will only have a single node that will manage the deployed application. Minikube is a simple version of a cloud-based Kubernetes Cluster that have multiple master and worker nodes. We will use Minikube to host our Dockerized FastAPI application.

Minikube is easy to set up because it usually comes with a Docker installation. As long as you are running Docker in your machine you have Minikube by default. 

NOTE: Minikube is only used when testing simple Kubernetes applications in the development environment. You can never use Minikube while in a production environment.

To check the version of Minikube that came with Docker, run this `minikube` comamnd:

```minikube
minikube version
```
To start a Minikube Kubernetes Cluster, run this `minikube` command:

```minikube
minikube start --driver=docker
```
The command will create and start a Minikube Kubernetes Cluster as shown below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/221j58ew88onh6ureyqa.png)

We have started a Minikube Kubernetes Cluster on our local machine. Before we deploy the Dockerized Fast API application we need to set up the Kubernetes CLI (kubectl).

### Getting started with the Kubernetes CLI
Kubernetes CLI (kubectl) is a powerful command line tool interface that allows DevOps engineers to communicate with a Kubernetes Cluster from the terminal. It has commands that allow you to manage and deploy Dockerized applications to the Kubernetes Cluster. There are different ways of installing the Kubernetes CLI. In this tutorial, we will install this tool using the following command:

```kubectl
choco install kubernetes-cli
```
To check if the installation was successful, run this `kubectl` command:

```kubectl
kubectl version --client
```
When you want to deploy an application to Minikube Kubernetes Cluster using Kubectl, you will need to create a Kubernetes YAML file. Let's talk about this file.

### Kubernetes YAML file
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](https://kubernetes.io/docs/concepts/services-networking/service/) for the application. Kubectl will use this file to deploy the Dockerized Fast API application to Minikube. In the `fast-api` folder, create a new file named `kubernetes.yaml`. Open the file and add the following code:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fast-api-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: fast-api
  template:
    metadata:
      labels:
        app: fast-api
    spec:
      containers:
      - name: fast-api
        image: bravinwasike/fast-api
        resources:
          limits:
            memory: "256Mi"
            cpu: "500m"
        ports:
        - containerPort: 8000
---

apiVersion: v1
kind: Service
metadata:
  name: fast-api-service
spec:
  selector:
    app: fast-api
  ports:
  - port: 8000
    targetPort: 8000
  type: LoadBalancer
```
The `kubernetes.yaml` is divided into two. The first part is known as `Deployment` while the second is known as `Service`.

**1. Deployment**
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 the `bravinwasike/fast-api` image from Docker Hub to create the Docker Container.

**2. Service**
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.

Let's apply Kubectl to this file:

```kubectl
kubectl apply -f kubernetes.yaml
```
The command will create a Kubernetes Deployment named `fast-api-deployment`. It will also create a Kubernetes Service named `fast-api-service`. Let's run the following commands to get the Kubernetes Deployment and Service:

**1. Kubernetes Deployment**
Run the following command:

```kubectl
kubectl get deployment
```
It gives the following output:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27flpy3wiugghc6wj1kt.png)

**2. Kubernetes Service**
Run the following command:

```kubectl
kubectl get service
```
It gives the following output:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w4fvdf0mmwz0y6ga4hcn.png)

### Accessing the Deployed FastAPI application
To access the deployed FastAPI application, Minikube will assign an External IP address to the `fast-api-service`. 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:

```minikube
minikube service fast-api-service
```
Minikube has assigned an External IP address to the `fast-api-service` as shown below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fb7wgdy0mtu99hkelfct.png)

Type the assigned IP address in your web browser to access your Dockerized FastAPI application:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p7s6c8y7iljpp80088wl.png)

Our Dockerized FastAPI application is running in the Minikube Kubernetes Cluster. Therefore, we have successfully dockerized and deployed a Fast API application to Kubernetes.

### Conclusion
In this tutorial, you have learned how to Dockerize and Deploy a Fast API application to Kubernetes. We started by creating and running a Fast API application locally. We then wrote a Dockerfile and used it to build a Docker Image for the FastAPI application.

We used the Docker Image to launch a Docker Container. Finally, we deployed the Dockerized Fast API application to the Minikube Kubernetes. We used the Kubernetes CLI and the Kubernetes YAML to deploy the application.