mr.bjerre
mr.bjerre

Reputation: 2888

CORS issues when running a dockerised FastAPI application

I have a fastapi application running and working just fine. I want to use my fastapi application to serve as backend for my react frontend deployed on firebase hosting (https). Running locally (http fastpi and react) I got it working by enabling CORS in FastAPI

from starlette.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

But when I deployed I realized that I couldn't serve fastapi as HTTP since my frontend is on HTTPS. I went ahead and created a kubernetes cluster in Google Cloud and ingressed my dockerised fastapi application (exposed as HTTPS). That works when I curl to my HTTPS fastapi endpoint but I'm getting CORS issues again in my react app and this time I don't know how to solve it. How come the above doesn't apply any longer?

The CORS error is

Access to fetch at 'https://my-api-domain' from origin 'https://my-frontend-domain' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

EDIT

I just did some further investigation and I can conclude that if I run my container locally with docker run then access-control-allow-origin is properly returned in the header. But when deployed on GKE then there are no access-control-allow-origin.

UPDATE

I've tried installing nginx ingress instead of GKE ingress but that complicates things regardin global static IP and google managed certificate. I need a solution that gives me

  1. Global static IP (ok with GKE ingress)
  2. Google Managed Certificate (ok with GKE ingress)
  3. CORS enabled (ok with nginx ingress)

So I'm stuck atm!

LATEST UPDATE

I'm using Nginx Ingress Controller with cert-manager and it works like a charm. Bonus info: running everything with skaffold and kustomize as well - so many great tools

Upvotes: 8

Views: 7534

Answers (2)

Amar Alikadic
Amar Alikadic

Reputation: 67

Adding the middleware after the default endpoint solved the issue for me.

app = FastAPI()
@app.get("/")

def home():
return {"message":"Health Check Passed!"}

app.add_middleware(CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],)

Upvotes: 4

PjoterS
PjoterS

Reputation: 14084

Posting this Community Wiki for better visibility as solution was mention in comment section.

If you would like to use CORS on Google Cloud Platform, you have to use Nginx Ingress and specific GCP annotation. More details about this you can find in this SO thread

kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/enable-cors: "true"

Solution

Solution for this issue was to use Nginx Ingress Controller and Cert-Manager with proper annotations.

Also OP confirmed it's working.

I'm using Nginx Ingress Controller with cert-manager and it works like a charm. Bonus info: running everything with skaffold and kustomize as well - so many great tools

Upvotes: 3

Related Questions