Recipe for using distroless container images with FastAPI

A few days ago I was trying to achieve that and took me a quite amount of time, is not so straight forward as you may think before trying it by yourself. In order to avoid you future headaches, here is a hack to use Distroless containers with FastAPI. In this example I’m trying to build an application with several requirements. The application basically allow you to download videos from Twitter using youtube-dl, you could test the application here also: Twittdown. Here is the structure of the application:


├── Dockerfile
├── main.py
├── requirements.txt
├── static
│   ├── ads
│   │   └── ads.txt
│   ├── bootstrap-5.1.3-dist
│   │   └── css
│   │       └── bootstrap.min.css
│   ├── font-awesome-4.7.0
│   │   └── css
│   │       └── font-awesome.min.css
│   └── main.css
└── templates
    └── index.html

The list of requirements is here also:


youtube_dl
jinja2
fastapi
pydantic
uvicorn[standard]

Now the main problem, how can I create a container for deploying this FastAPI application using a distroless image? Here is the trick


FROM python:3.10-slim AS build-env

COPY . /app

WORKDIR /app

RUN pip install --no-cache-dir --upgrade -r requirements.txt && cp $(which uvicorn) /app

FROM gcr.io/distroless/python3

COPY --from=build-env /app /app
COPY --from=build-env /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
ENV PYTHONPATH=/usr/local/lib/python3.10/site-packages

WORKDIR /app

CMD ["./uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]

Enjoy! If you find a cleaner way let me know ).