Using Python FastAPI. Web server running apache how to serve static folder over HTTPS

Question:

When using FastAPI all files in my static folder are served over HTTP and not HTTPS. To be more clear they’re not being severed over my domain but the localhost of my webserver. I’m assuming this is something between how my webserver is setup and the mount function of FastAPI.

I’m hosting using Apache, with a domain, static IP, and https certificate. No issues with Flask or NodeJS on the same server.

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

app = FastAPI()

templates = Jinja2Templates(directory="templates/")

app.mount("/static", StaticFiles(directory="static"), name="static")

@app.get("/home/", response_class=HTMLResponse)
async def home(request: Request):
   return templates.TemplateResponse("home.html", {"request": request})

ERROR:

Mixed Content:  
The page at 'https://www.<insert-domain>.com' was loaded over HTTPS,   
but requested an insecure element 'http://localhost:3000/static/logo.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

Asked By: Blake A

||

Answers:

TL;DR

Try to include the needed ssl configuration in your application,
that way FastAPI would know how to serve server over HTTPS.
Please try the following:

app = FastAPI(
    ssl_keyfile="/path/to/your/private.key",
    ssl_certfile="/path/to/your/certificate.crt"
)

The Reason You Get This Error

You get the mentioned error about mixing both secure and insecure elements in your website. It seems like you access your domain it has the needed SSL certificates, but when you access the static files that are stored locally you are fetching things from localhsot without knowing they exist. FastAPI the way you’ve configured it does not know how to serve those files over HTTPS. Thus, you get the exact problem of accessing https://www.example.com and http://localhost at the same time which is no longer supported by chrome.

Resolving the Issue

In order to create a FastAPI app and configure it in a way it is served securely, you need to mention the ssl keys and certificates as part of the configuration on the application. That way, when you are accessing the site, you’ll have HTTPS. Adding the needed ssl_keyfile and ssl_certfile as parameters to FastAPI constructor should do the trick. (Please see the above code snippet)

HTTPS Is More Complex than That

I highly recommend taking the time to dive deep into the subject and read more about the subject at FastAPI documentation site. As mentioned there:

It is easy to assume that HTTPS is something that is just "enabled" or not.
But it is way more complex than that.

Some Things to Notice Before Hitting Production

You should consider multiple factors when you deploy your site.
According to your description of the error, it seems like something might not be configured correctly.
For some reason, the server access localhost in order to fetch the logo of the site/application. This might work when you are in the development area, but when you reach production environment is might break things. I would expect the server to fetch all static files from the server (using the domain) without trying to access some local stuff. Make sure the server is configured the right way.

Further Reading

If you are looking for some further examples about configuration for running the server manually, you can read more about that in the following blog posts:

If you are interested in checking the best practices regarding deployment settings, the FastAPI documentation site would be a good start – covering the basics and offering some ground rules:

Answered By: Matan Itzhak
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.