I can tell you to create a virtual environment, activate it, and start the fastapi application with the uvicorn server. However, so far, I have worked at 4 organizations and everywhere I have seen docker being the de-facto way to run applications.
This is because it makes our product platform independent. This helps eliminate, "It works on my machine!". A project may work on Linux but not on Windows or Mac. In case it is dockerized, it is bound to work on all operating systems.
Directory Structure:
🌳 C:\Users\soura\fastapi\gptapi
├── 📄 Dockerfile
├── 📄 main.py
└── 📄 requirements.txt
I like to first implement something and then introspect on how it works. I will be following the same strategy here too.
Hey, we will need to have fastapi installed first. In order to install fastapi and uvicorn(the webserver that runs the fastapi application), let's put them in a requirements.txt file.
fastapi==0.110.0
uvicorn==0.29.0
Let's begin with implementing a main.py file for FastAPI.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
return {"Hello": "There"}
Now, let us create dockerfile. A dockerfile corresponds to a docker image or snapshot of a system. Consider it like specifying the operating system and some set of instructions that you want to execute in the operating system to prepare the OS to run the fastapi application.
FROM python:3.9-slim
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
COPY . /app/
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Most of the commands are self-explanatory. We take a Linux OS and prepare it for running Python applications. Instead of starting as a base linux image like Ubuntu, we choose a pre-prepared lightweight Linux image python:3.9-slim.
-
ENV PYTHONDONTWRITEBYTECODE 1
: This sets an environment variable to instruct Python to not write bytecode files (.pyc) to disk. Bytecode files are typically generated by Python when it imports modules and can speed up subsequent imports, but in certain scenarios, such as containerized environments, they may not be necessary. -
ENV PYTHONUNBUFFERED 1
: This sets another environment variable to prevent Python from buffering its standard output and standard error streams. When set to1
, Python prints output directly to the terminal without buffering, which can be useful for logging and debugging in containerized environments. -
RUN pip install --no-cache-dir -r requirements.txt
: This installs the Python dependencies listed in therequirements.txt
file using pip. The--no-cache-dir
flag tells pip not to cache the downloaded packages, which can help reduce the size of the Docker image.
Let's build and run this docker file and experiment with it to better understand the other lines.
docker build -t gpt-api .
docker run -p 8000:8000 gptapi
Now, you can visit http://127.0.0.1:8000/docs and try out the /route using the swagger API docs.
One last thing, I would suggest adding a .dockerignore file. This is similar to the concept of .gitignore, it helps us avoid adding some folders and files to docker image which are generally very large. So, create a new file, .dockerignore
#.dockerignore file
env
env/