4

Description I have a React application that makes the following request:

await axios.get(`${process.env.REACT_APP_MASTER_HOST}/api/agl-history`, { headers: { Authorization: `Bearer ${token}` }, data: { label, date } });

In some cases it works but when the backend is started with docker-compose up -d, it gives me the following in Chrome:

Access to XMLHttpRequest at 'http://localhost:8080/api/agl-history' from origin 'http://localhost:3000' 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.

When it works

  • When I manually build the image with sudo docker build . -t test and run, sudo docker run -p 8080:8080 -t test, it works perfectly
  • When I run the flask server with flask run --host=0.0.0.0

When it does not work

  • docker-compose up -d

// docker-compose.yml, relevant service is master

version: "3.9"
services:
  agl-history:
    depends_on:
        - mariadb
    build: ./agl-history
    restart: on-failure
    networks:
        - main
  master:
    depends_on:
        - mariadb
    build: ./master
    restart: on-failure
    ports:
        - 8080:8080
    networks:
        - main
  mariadb:
    image: "mariadb:10.5.10"
    restart: on-failure
    environment: 
        MYSQL_ROOT_PASSWORD: ${MARIADB_PASSW}
    ports:
        - 3306:3306
    volumes:
        - /var/lib/docker/volumes/add3-data:/var/lib/mysql
    networks:
        - main
networks:       
    main:
        driver: bridge

// Dockerfile

FROM python:3.9.5-buster

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

COPY . .

ENV FLASK_RUN_PORT 8080
ENV FLASK_APP source/server_config.py

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

// Flask endpoint

from datetime import date
from flask import Flask
from flask import jsonify
from datetime import datetime
from flask_cors import CORS

# app reference
app = Flask(__name__)
cors = CORS(app)

# This method executes before any API request
@app.before_request
def before_request():
    print('before API request')

@app.route('/api/agl-history', methods=['GET'])
def get_agl_history():
    print('during')
    response = jsonify([
        {
            'id': 1,
            'customerId': 777,
            'campaignName': 'Test campaing',
            'adGroupName': 'Test ad group',
            'execDate': datetime.now(),
            'label': '92'
        }
    ]
    )
    return response

# This method executes after every API request.
@app.after_request
def after_request(response):
    return response

Notes

  • React frontend and server backend is going to be run on different hosts eventually

What am I doing wrong? Any help is greatly appreciated! Thanks!

4 Answers4

0

I think the issue comes from your Flask backend and it's CORS headers. I'd suggest using --host=127.0.0.1 in your flask command. Also, check this answer, it provides a lot of information.

theUndying
  • 1,526
  • 3
  • 11
0

It could be that browser is sending preflight ( OPTIONS ) request because you have Authorization headers , i had same problem before with react dev server and express,

I solved the problem with , OPTIONS route on same path with :

Access-Control-Request-Headers : Authorization

But i am maybe wrong here , because cors is confusing thing :)

Shomy
  • 31
  • 4
0

Browers issue preflight request(OPTION call) when the origin (frontend localhost:3000) is different from the API origin (localhost:8080)

For development, you can allow all the origin in the flask server. This is the default configuration. Seems this is the case with your working scenarios

But when running via the docker-compose the hostname of the flask server would be master. From your failing scenario, it seems, flask does only accept from that hostname.

So when deploying in a production environment I would suggest adding cors origin configuration allowed origin as front end domain

For your docker-compose scenario, you could configure below in flask server

CORS_ORIGINS: “localhost:3000”
Vinujan.S
  • 1,199
  • 14
  • 27
0

I did not realize that docker-compose does not rebuild images by default so I was using an older build that did not have CORS enabled.

The only change that was needed to fix the issue was:

cors = CORS(app, origins="*")

when starting flask server. Then, start the services with:

sudo docker-compose up -d --build master