Home > Software design >  Docker - React app can not fetch from the server
Docker - React app can not fetch from the server

Time:06-18

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.

CodePudding user response:

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

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

  • Related