Getting Started with FastAPI and Docker
Published: 2023-02-24 07:57:48

[FastAPI](https://fastapi.tiangolo.com/deployment/docker/) is a modern, fast (hence the name), web framework for building APIs with Python. It is built on top of Starlette for the web server, Pydantic for data validation and serialization, and provides automatic API documentation using OpenAPI and JSON Schema.

The architecture of FastAPI is based on the following key components:

- **ASGI**: FastAPI is based on the ASGI (Asynchronous Server Gateway Interface) specification, which allows for high-performance asynchronous request handling.

- **Starlette**: FastAPI is built on top of Starlette, a lightweight ASGI framework for building high-performance async web services. Starlette provides a lot of the underlying functionality of FastAPI, such as request and response handling, routing, and middleware support.

- **Pydantic**: FastAPI uses Pydantic, a data validation and serialization library, to define the data models for API input and output. Pydantic provides powerful validation and serialization capabilities that make it easy to define and validate complex data structures.

- **OpenAPI**: FastAPI automatically generates OpenAPI documentation for your API based on your code, making it easy to document your API and to generate client code in other programming languages.

- **Dependency Injection**: FastAPI provides built-in dependency injection, allowing you to easily inject dependencies (such as database connections or other services) into your API functions.

The architecture of FastAPI is designed to be fast, easy to use, and highly scalable. By leveraging the power of ASGI, Starlette, Pydantic, and OpenAPI, FastAPI provides a modern, high-performance framework for building APIs with Python.


## Why to containerise FastAPI?

There are several reasons why you might want to containerize a FastAPI application:

- **Portability**: Containers provide a lightweight and portable way to package and deploy applications, making it easy to move your application from one environment to another, such as from your local development environment to a production server.

- **Consistency**: By containerizing your application, you can ensure that it will run the same way in any environment, without having to worry about differences in operating system, system libraries, or other dependencies.

- **Isolation**: Containers provide a level of isolation between your application and the host operating system, which can help to improve security and stability.

- **Scalability**: Container orchestration platforms like Kubernetes or Docker Swarm make it easy to scale your application horizontally by adding or removing container instances, providing an efficient and flexible way to handle changes in demand.

- **Reproducibility**: By using a Dockerfile to build your container image, you can reproduce your application environment at any time, making it easier to troubleshoot issues or test new features.

Containerizing your FastAPI application can help to streamline your development and deployment processes, improve consistency and portability, and make it easier to scale and manage your application in production.

## Getting Started

## Pre-requisite

- Install Docker Desktop 

## Step 1. Create a new directory for your project and navigate into it:

```
mkdir fastapi-docker
cd fastapi-docker
```

## Step 2. Create a new Python virtual environment:

```
python -m venv venv
```

## Step 3. Activate the virtual environment:

```
source venv/bin/activate
```

## Step 4. Install FastAPI and uvicorn:

```
pip install fastapi uvicorn
```

## Step 5. Create a new file called main.py and add the following 

```
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: str = None):
    return {"item_id": item_id, "q": q}
```

## Step 6. Create a new file called Dockerfile and add the following code:

```
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9

COPY ./app /app
```

This Dockerfile is based on the tiangolo/uvicorn-gunicorn-fastapi image, which includes everything needed to run a FastAPI application using uvicorn and gunicorn.

The COPY command copies the contents of the app directory (which will contain our main.py file) into the /app directory in the Docker container.

## Step 7. Create a new directory called app and move the main.py file into it:

```
mkdir app
mv main.py app/
```

## Step 8. Build the Docker image:

```
docker build -t fastapi-docker .
```

This command will build the Docker image using the Dockerfile in the current directory and tag it with the name fastapi-docker.

## Step 9. Run the Docker container:

```
docker run -p 8000:80 fastapi-docker
```

This command will start a new Docker container and map port 80 inside the container to port 8000 on the host machine.

You can now test your FastAPI application by visiting http://localhost:8000 in your web browser or making HTTP requests to it using a tool like curl.


```
$ curl http://192.168.0.13:8000
{"Hello":"World"}[node2] (local) root@192.168.0.12 ~
$ 
```



That's it! You have now containerized a FastAPI application using Docker.

## Using Docker Compose

If you're looking out for Docker compose-specific sample app, head over to [Docker Awesome-Compose repository](https://github.com/docker/awesome-compose/tree/master/fastapi)

## Clone the Repository

```
git clone https://github.com/docker/awesome-compose/
cd awesome-compose/fastapi
```

```
services:
  api:
    build: .
    container_name: fastapi-application
    environment:
      PORT: 8000
    ports:
      - '8000:8000'
    restart: "no"
```

## Running the Containers

```
docker compose up -d
```

## Listing the containers

```
docker compose ps
NAME                  COMMAND             SERVICE             STATUS              PORTS
fastapi-application   "/start.sh"         api                 running             80/tcp, 0.0.0.0:8000->8000/tcp
```


After the application starts, navigate to http://localhost:8000 in your web browser and you should see the following json response:


```
{
"message": "OK"
}
```

## Stop and remove the containers

```
$ docker compose down
```