Home > Software engineering >  React prod build front end not using proxy to access back end
React prod build front end not using proxy to access back end

Time:12-20

I 've built a react app that runs noermally in dev but when I prod build it the front end fetch requests dont use the proxy I've specified in the package.json file.

fetch request:

export const verifyUser = async (user) => {
  console.log(user);
  const newData = await fetch("/login", {
    method: "POST",
    body: JSON.stringify({ name: user.username, password: user.password }),
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
    },
  }).then((res) => res.json());
  return newData;
};

package.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://host.docker.internal:8080",
  "dependencies": {
    "@craco/craco": "^6.4.3",
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.1.1",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@tailwindcss/postcss7-compat": "^2.2.17",
    "autoprefixer": "^9.8.8",
    "postcss": "^7.0.39",
    "postcss-cli": "^9.1.0",
    "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17"
  }
}

ui Dockerfile:

# build environment
FROM node:14.18.1 as build
WORKDIR /app
COPY package*.json ./
COPY . .
RUN npm ci
RUN npm run build

# production environment
FROM nginx:1.21.4-alpine
COPY --from=build /app/build /usr/share/nginx/html
COPY --from=build /app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD [ "nginx","-g", "daemon off;"]

docker-compose:

version: "3"
services:
  api:
    build: ./api
    ports:
      - "8080:8080"
    depends_on:
      - mongo
  ui:
    build: ./my-app
    ports:
      - "80:80"
    depends_on:
      - api
  mongo:
    image: mongo
    ports:
      - "27017:27017"

I've tried putting the full address in the fetch call and it did not work nginx.config:

server {
    listen 80;
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }
}

CodePudding user response:

You need to make Nginx pass the calls to your API through to your API container. A common way to do that is to prefix all API requests with /api/, so your /login endpoint becomes /api/login.

If you change your nginx.conf to

server {
    listen 80;
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html =404;
    }

    location /api/ {
        proxy_pass http://api:8080/;
    }
}

then it'll pass on the requests. That means that you also need to change your fetch call to

  const newData = await fetch("/api/login", {

Since you always access the api container through the nginx container, there's no need to map the api container port to a port on the host and you can remove that in your docker-compose file

  api:
    build: ./api
    depends_on:
      - mongo
  • Related