Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set up nginx proxy for react application

I'm trying to create a docker-compose using two services, a Spring Boot backend (running on port 8080) and React frontend running on Nginx.

The react app calls backend API like /api/tests. However, when I run the docker compose and frontend makes a request, it always fails with 404 error: GET http://localhost/api/tests 404 (Not Found)

When I set the frontend dockerfile not to use Nginx, just npm start, it worked fine, but I would prefer using production build on Nginx.

Current frontend dockerfile:

FROM node:11.13 as builder

RUN mkdir /usr/src/app
WORKDIR /usr/src/app

ENV PATH /usr/src/app/node_modules/.bin:$PATH

COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install [email protected] -g

COPY ./package-lock.json /usr/src/app/
COPY ./public /usr/src/app/public
COPY ./src /usr/src/app/src

COPY ./nginx.conf /etc/nginx/nginx.conf

RUN npm run build

FROM nginx:1.15.10-alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]

Nginx.conf:

server {
    listen 80;

    location / {
        try_files $uri $uri/ /index.html;
        add_header   Cache-Control public;
        expires      1d;
    }

    location /api {
       proxy_set_header X-Forwarded-Host $host;
       proxy_set_header X-Forwarded-Server $host;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_pass http://server:8080/;
    }
}

docker-compose:

version: "3"

services:
  server:
    build: test-server/
    expose:
      - 8080
    ports:
      - 8080:8080
  ui:
    build: test-ui/
    expose:
      - 80
    ports:
      - 80:80

The react app has a line "proxy": "http://server:8080" in its package.json.

Nginx logs the following error:

2019/04/15 12:50:03 [error] 6#6: *1 open() "/usr/share/nginx/html/api/tests" failed (2: No such file or directory), client: 172.20.0.1, server: localhost, request: "GET /api/tests HTTP/1.1", host: "localhost", referrer: "http://localhost/"
like image 304
fugasjunior Avatar asked Apr 15 '19 12:04

fugasjunior


People also ask

How do you proxy A React app?

Proxy Setup with Create-React-App All you have to do is add a proxy field to your package. json file, like shown below. "proxy": "http://localhost:3000", This line instructs the development server to proxy any unknown requests to your API server in development mode.

Can Nginx act as proxy?

Nginx is an open source web server that can also serve as a reverse proxy. Apart from being used to host websites, it's also one of the most widely used reverse proxy and load balancing solutions.

Why you should use a proxy server with create-React-app?

Proxy servers can assist in redirecting requests to APIs without having to go via the browser's default request options, which helps to evade several cross-origin limitations. Second is fetching data from cross-origin APIs that don't support CORs in web browsers.


1 Answers

I found the problem. In the multi-stage build of the docker image, I accidentally copied the nginx.conf file into the builder image, not the production one.

The fixed Dockerfile now looks like this:

# build environment
FROM node:11.13 as builder

RUN mkdir /usr/src/app
WORKDIR /usr/src/app

ENV PATH /usr/src/app/node_modules/.bin:$PATH

COPY package.json /usr/src/app/package.json
RUN npm install
RUN npm install [email protected] -g

COPY ./package-lock.json /usr/src/app/
COPY ./public /usr/src/app/public
COPY ./src /usr/src/app/src


RUN npm run build

# production environment
FROM nginx:1.15.10-alpine
COPY --from=builder /usr/src/app/build /var/www
COPY ./nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]

and nginx.conf:

server {
    listen 80;
    include /etc/nginx/mime.types;
    root /var/www;
    index index.html index.htm;
    location /api {
        resolver 127.0.0.11;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://server:8080$request_uri;
    }
    location / {
        try_files $uri $uri/ =404;
    }
}
like image 90
fugasjunior Avatar answered Sep 20 '22 13:09

fugasjunior