Fastapi with jinja rendered image does not display image inside container run

100 Views Asked by At
from routers import routers_main
app = FastAPI()

#Mount the static files directory
app.mount("/static", StaticFiles(directory="static"), name="static")
app.include_router(routers_main.router)

My router file has the following

router = APIRouter()

@router.get("/", response_class=HTMLResponse)
def home_page(request: Request):
    image_url_1 = request.url_for("static", path=f"website_flow.png")
    return templates.TemplateResponse("home.html", {"request": request, "visits": visits, "image_1": image_url_1})

Inside the html I have added this

  <img src="{{ image_1 }}" alt="Image 12" style="width: 100%; height: auto;">

It displays correctly with uvicorn locally but the issue occurs when I run the fastapi as a container with the command

CMD ["gunicorn", "-b", "0.0.0.0:3400", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "main:app"]

The directory structure is

--- main.py
--- router/
------ routers_main.py
--- static/
------ website_flow.png

The container is working correctly in macos but fails in the container of aws apprunner

My dockerfile:

# pull official base image
FROM python:3.11.2-slim-buster

RUN pip install --upgrade pip
COPY ./requirements.txt .
# Install PyTorch and torchvision with cpu
RUN pip install -r requirements.txt
RUN pip3 install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cpu

# add app
COPY . .

# Specify the command to be executed when running the container
# CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]
# CMD ["gunicorn -b 127.0.0.1:3100 -w 4 -k uvicorn.workers.UvicornWorker main:app"]
CMD ["gunicorn", "-b", "0.0.0.0:3400", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "main:app"]
# RUN THE BELOW COMMAND AFTER BUILDING
# docker run -d -p 3400:3400 --name my-container my-dock

The container displays html correctly in local but does not do so in aws apprunner container. I get the following in the browser console which is missing in my local browser console

Mixed Content: The page at 'https://nhs6qhaxjj.us-east-1.awsapprunner.com/' was loaded over HTTPS, but requested an insecure element 'http://nhs6qhaxjj.us-east-1.awsapprunner.com/static/telugu_dictionary_flowchart.png'. This request was automatically upgraded to HTTPS, For more information see https://blog.chromium.org/2019/10/no-more-mixed-messages-about-https.html
website_flow.png:1 
        
        
       Failed to load resource: the server responded with a status of 404 (Not Found)

dockerfile is in same directory as main.py

I have tried the following:

Adding this tag to the header tag of html

< meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

Adding middleware

 from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
app.add_middleware(HTTPSRedirectMiddleware)

I strongly suspect there's an issue with AWS containers or the issue is arising due to macos (my local OS) and ubuntu difference

Edit: Trying out from the suggestions in the github issue:

  1. @app.middleware("http")
  2. app.add_middleware(HTTPSRedirectMiddleware)
  3. --proxy-headers with uvicorn and guvicorn

None of these work. My fastapi version is fastapi==0.100.0 with starlette==0.27.0

1

There are 1 best solutions below

3
On

After the update on the question, the error is self explanatory:

The issue is caused by the fact that your client's browser is requesting an insecure URL after using a secure one to connect to your app. Probably this is a misconfiguration of your server, but you should be capable of setting somewhere (I don't know the aws ecosystem) to force redirect. FastAPI should automatically adapt to use https.

Below a link with the complete answer to the same problem

How to fix "insecure content was loaded over HTTPS, but requested an insecure resource"