Setting up FastAPI with Docker

In this blog we'll discuss setting up a minimal starter template for building API with FastAPI and Docker.

I'll start by creating directories. I'll create one for the app and one for docker.

mkdir docker 
mkdir app

I'll setup the app directory first.

This involves setting up the virtual env, creating a init.py file and a sample fastapi app with a GET endpoint.

To create the init.py file, I'll use the touch command.

cd app
touch __init__.py

To create the virtual env i'm going to use virtualenv package. You can use pipenv or any other method your familiar with.

You can create the virtualenv outside the app directory.

virtualenv env 

To install fastapi in the virtualenv use :

pip install fastapi

Next we'll create a sample fastapi app with a test endpoint.

from fastapi import FastAPI, status


app = FastAPI()


@app.get("/")
def home():
    return {"message": "home", "status": status.HTTP_200_OK}

Now I'll move to the docker directory.

We'll need 2 files

  • Dockerfile : File for describing the container image.
  • docker-compose.yml : Yaml file describing the runtime for the image. Useful, when running multi container apps.
Dockerfile
FROM python:3

ENV pythonunbuffered 1
ENV PYTHONDONTWRITEBYTECODE 1

WORKDIR /myproject

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

COPY . .

Explanation for the above file :

The from command describes the base image we want to use for the container image.

ENV is used to set environment variables for the image being built.

WORKDIR sets the current working directory and every command below will be run from that dir.

COPY command copies files and directories from the host to the container image.

RUN command executes the command in the container shell during the build process.

Thats all for the dockerfile.

The docker-compose.yml is a yaml file that describes a service and its deps. We only have one service here, our api service.

services:
  api:
    build:
      dockerfile: docker/Dockerfile
      context: ..

    command: fastapi dev --host 0.0.0.0 /myproject/app/app.py
    ports:
      - 8000:8000

All container specs are described under services.

We'll name our service api. The build block lets you specify how the container is to built. I given the name of the dockerfile and the service built context.

command, kinda obvious lets you run the starter script or program.

ports key lets us specify the port mapping between the host and the container port. The first part is for the host and the second part is the container port.