nginxhttpsfastapireverse-proxystarlette

FastAPI (Starlette) + NGINX Proxy: URL scheme in Request Object not correct?


I'd like to know the following

The setting is like this:

I have a FastAPI app running behind a NGINX proxy. Via the browser, I send requests to NGINX via HTTPS (https://www.example.com) , but whatever I do, request.url on Starlette's side is always http://www.example.com.

I made a small FastAPI endpoint for demonstration purposes

@app.get("/test")
def some_test(request: Request):
    return {"request.url": request.url,
            "request['headers']": request["headers"],
            "request.client": request.client}

and in the following screenshots I show what I get (domain is anonymized; set to xyz): enter image description here

  1. I call in the browser https://www.example.com/test
  2. In the console, I see that properly the request is issues to https://www.example.com/test
  3. But when looking at Starlette's Request.url, it says http://www.example.com/test

Is this behaviour how it should be? In the screenshot I also print the host and x-forwarded-proto and x-forwarded-schema which I set the NGINX config to HTTPS, but the object Request isn't modified at all by that.

What can I do to correct this on the NGINX or FastAPI/Starlette level?


Solution

  • Now the proxying of the schema works.

    The problem was,the following:

    Before my Dockerfile looked like

    ENTRYPOINT ["uvicorn", "main:app", "--proxy-headers", "--forwarded-allow-ips='*'", "--host", "0.0.0.0"]
    

    The quotation marks in the --forwarded-allow-ips parameter do not work. Instead the entrypoint should read

    ENTRYPOINT ["uvicorn", "main:app", "--proxy-headers", "--forwarded-allow-ips=*", "--host", "0.0.0.0"]
    

    Hint: To be a bit cleaner, one should not allow * as an IP address, instead you should specify the IP address.