0

Hello I am new to the docker and I am trying to dockerize my application that uses React as frontend, nodejs as backend and mySQL as database. However when I try to fetch data from server from my react app, it gives me error:

Access to fetch at 'http://localhost:3001/api' from origin 'http://localhost:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:3000' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

My react app is rendered and also when I go to http://localhost:3001/api I receive the data I would like to get. Just the communication between react and nodejs is somehow broken.

Here are my Docker files and env files:

.env:

DB_HOST=localhost
DB_USER=root
DB_PASSWORD=123456
DB_NAME=testdb
DB_PORT=3306
MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=123456
MYSQLDB_DATABASE=testdb
MYSQLDB_LOCAL_PORT=3306
MYSQLDB_DOCKER_PORT=3306
NODE_LOCAL_PORT=3001
NODE_DOCKER_PORT=3001
CLIENT_ORIGIN=http://127.0.0.1:3000
CLIENT_API_BASE_URL=http://127.0.0.1:3001/api
REACT_LOCAL_PORT=3000
REACT_DOCKER_PORT=80

dockerfile for react:

FROM node:14.17.0 as build-stage
WORKDIR /frontend
COPY package.json .
RUN npm install
COPY . .
ARG REACT_APP_API_BASE_URL
ENV REACT_APP_API_BASE_URL=$REACT_APP_API_BASE_URL
RUN npm run build

FROM nginx:1.17.0-alpine
COPY --from=build-stage /frontend/build /usr/share/nginx/html
EXPOSE 80
CMD nginx -g 'daemon off;'

dockerfile for nodejs:

FROM node:14.17.0
WORKDIR /
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3001
CMD [ "node", "server.js" ] 

docker-compose.yml :

version: '3.8'
services: 
  mysqldb:
    image: mysql
    restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - MYSQL_DATABASE=$MYSQLDB_DATABASE
    ports:
      - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
    volumes:
      - db:/var/lib/mysql
    networks:
      - backend
  server-api:
    depends_on:
      - mysqldb
    build: ./
    restart: unless-stopped
    env_file: ./.env
    ports:
      - $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
    environment:
      - DB_HOST=mysqldb
      - DB_USER=$MYSQLDB_USER
      - DB_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - DB_NAME=$MYSQLDB_DATABASE
      - DB_PORT=$MYSQLDB_DOCKER_PORT
      - CLIENT_ORIGIN=$CLIENT_ORIGIN
    networks:
      - backend
      - frontend
  frontend-ui:
    depends_on:
      - server-api
    build: 
      context: ./frontend
      args:
        - REACT_APP_API_BASE_URL=$CLIENT_API_BASE_URL
    ports:
      - $REACT_LOCAL_PORT:$REACT_DOCKER_PORT
    networks:
      - frontend  
volumes: 
  db:
networks:
  backend:
  frontend:

My project folder structure is a bit weird as my server its things(node_modules, package.json...) are in the root where docker-compose, .env and Dockerfile for server is located.
React app and frontend is in /frontend folder where also Dockerfile for react is located.

In react I call fetch("http://localhost:3001/api").

Server is created with express :

const express = require('express');
const cors = require('cors');
const server = express();
var mysql = require('mysql2');
require("dotenv").config();

const port = 3001

server.use(express.static('public'));

var corsOptions = {
    origin: "http://127.0.0.1:3000"
}

server.use(cors(corsOptions));

var con = mysql.createConnection({
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD
});

server.get('/api', async (req, res) => {
  console.log("START");
  con.connect(function (err) {
    if (err) throw err;
    console.log("connected !");
    con.query("use testdb;", function (err, result, fields) {
      if (err) throw err;
      console.log(result);
    });
    con.query("select * from records;", function (err, result, fields) {
      if (err) throw err;
      res.send(result);
    });
  });
});


server.listen(port, () => {
    console.log(`Server listening on port ${port}`)
})


I created this thanks to This tutorial
Thanks for any help.

3
  • 3
    change this: origin: "http://127.0.0.1:3000" to: origin: "http://localhost:3000" Commented Jun 16, 2022 at 14:19
  • @bmz1 Wow ! Thank you very much, I would never thought that the problem is this. :D Thanks, now it works Commented Jun 16, 2022 at 14:57
  • 1
    I'm writing it as an answer, so pls accept it Commented Jun 17, 2022 at 9:55

1 Answer 1

1

change this: origin: "http://127.0.0.1:3000"

to this: origin: "http://localhost:3000"

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.