Containerizing a FastApi App using Nginx as a Proxy(Part One)

Adebisi Olayinka
4 min readNov 24, 2023

--

This is a three-part series. This article will focus more on creating and containerization while in part two I will set up the proxy and finally in part three, we will be deploying our FastApi app to the cloud, by incorporating the deployment of the app into a GitHub Actions pipeline.

Background:

I recently had a somewhat hectic experience containerizing and deploying a FastApi application and this was partly due to the lack of sufficient resources which would have greatly improved my experience. While this isn’t necessarily a replica of the project I worked on, I believe that this tutorial will cover the same core concepts.

Set Up and Installation

To get started with the tutorial, we need to create a project directory

mkdir fastapicourse

Change directories into the newly created one:

cd fastapicourse

Following the default FastApi installation guide, make sure you have Python installed and added to your Path before running this command.

pip install fastapi

We will also need an ASGI server like uvicorn. Why do we need uvicorn?

pip install "uvicorn[standard]"

You can then open up the directory using your favorite code editor. I will be using Visual Studio Code for the rest of the tutorial.

Create a file called main.py and populate it with the code below. In essence, it’s a simple API with greetings at the root and an endpoint for handling items with associated IDs and optional queries.

from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}

Save the file and run the following command in your terminal:

uvicorn main:app --reload

If you’ve been following along, you should see output that indicates the app started up successfully:

Create a file named requirements.txt in the project directory and add the following lines:

fastapi
uvicorn

The requirements.txt will be used to install the dependencies for the project when we set up the container.

Containerization

After making sure you’ve set up docker and have it running, you may proceed with this part of the tutorial.

Create a dockerfile in the root directory of the fastapicourse directory and add the following config to it.

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

FROM python:3.11-slim: This line tells Docker to start building the image from the official Python 3.11-slim image. This image is a slimmed-down version of the official Python image, which means that it contains only the essential packages needed to run Python.

WORKDIR /app: This line sets the working directory for the container to /app. This means that all subsequent commands will be executed relative to this directory.

COPY requirements.txt .: This line copies the file requirements.txt from the local machine to the working directory of the container. The requirements.txt file contains a list of dependencies we specified earlier that the application needs to run.

RUN pip install -r requirements.txt: This line runs the pip command to install the Python packages listed in the requirements.txt file. This will install all of the dependencies that the application needs to run.

COPY . .: This line copies all of the files from the local machine to the working directory of the container. This means that the application’s source code and any other files that the application needs will be available in the container.

EXPOSE 8000: This line exposes port 8000 of the container. This means that the container will be able to listen for traffic on this port.

CMD [“uvicorn”, “main: app”, “ — host”, “0.0.0.0”, “ — port”, “8000”]: This line sets the command that will be run when the container is started. The command will run the Uvicorn ASGI server, which will serve the application on port 8000.

Build the Docker image:

Create a docker-compose.yml file in the project directory and add the following:

version: "3"

services:
app:
build: .
ports:
- "8000:8000"

The docker-compose specifies a service named app and by running this command in your terminal:

docker-compose up

or run:

docker-compose up -d

to run the app in detached mode, the “app” container will be created and the container will run on the exposed port in the dockerfile. You should get a result like this in your terminal:

If you get the FastAPI app running successfully, you can now visit http://localhost/docs to view the default page for FastApi

Congrats! You have successfully containerized a FastApi application. Please read the follow-up article where I set up the proxy.

--

--