Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx reverse proxy and multiple React apps

So I'm trying to use NGINX as a reverse proxy for 2 react apps and 1 node js api. Each in separate docker containers.

So for example,

  • localhost -> leads to one react app

  • localhost/admin -> leads to another react app

  • localhost/api/getProducts -> leads to the /getProducts endpoint of the api

The first example and the second both work as intended. No issues. It's the 2nd example I'm having trouble configuring. It should just lead to a dashboard application built in React, but all I get is a white screen (with the same favicon as the first react app).

Here is my nginx config file

    upstream api {
        least_conn;
        server api:8080 max_fails=3 fail_timeout=30s;
    }

    upstream app {
        least_conn;
        server app:3000 max_fails=3 fail_timeout=30s;
    }

    upstream adminapp {
        least_conn;
        server adminapp:3001 max_fails=3 fail_timeout=30s;
    }

    server {
        listen 80;

        if ($request_method = 'OPTIONS') {
            return 200;
        }

        # To allow POST on static pages
        error_page  405     =200 $uri;

        location / {
            proxy_pass http://app;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            expires 30d;
            break;
        }

        location ~ /admin/(?<url>.*) {
            proxy_pass http://adminapp;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            expires 30d;
            break;
        }

        location ~ /api/(?<url>.*) {
            proxy_pass http://api/$url;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

        location /health-check {
            return 200;
            access_log off;
        }
    }

}

When I specifically go to localhost:3001, I can reach the admin dashboard so I know it's running perfectly fine.

Here's my docker compose file as well

version: '3.7'

services:
  nginx:
    container_name: nginx
    image: nginx
    ports:
      - '80:80'
      - '443:443'
    links:
      - api:api
      - app:app
      - adminapp:adminapp
    volumes:
      - ./server/config/nginx:/etc/nginx
      - ./server/config/certs:/etc/ssl/private
  app:
    container_name: app
    build:
      context: ./frontend
      dockerfile: Dockerfile
    volumes:
      - './frontend:/usr/app/frontend/'
      - '/usr/app/frontend/node_modules'
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development
  adminapp:
    container_name: adminapp
    build:
      context: ./admin
      dockerfile: Dockerfile
    volumes:
      - './admin:/usr/app/admin/'
      - '/usr/app/admin/node_modules'
    ports:
      - '3001:3001'
    environment:
      - NODE_ENV=development
      - PORT=3001
  api:
    container_name: api
    build:
      context: ./backend
      dockerfile: Dockerfile
    volumes:
      - './backend:/usr/app/backend/'
      - '/usr/app/backend/node_modules'
    ports:
      - '8080'
    environment:
      - NODE_ENV=development
like image 718
KFrancis Avatar asked Mar 08 '20 01:03

KFrancis


1 Answers

Leaving an answer here because I figured it out. Basically you have to add "homepage": "." to your package.json first. Then, make sure you check your dockerfile. This was my mistake. For it to work on a subdomain you have to explicitly build everything in the Dockerfile as it is here:

FROM node:14-alpine as build-deps
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn
COPY . ./
RUN yarn build

FROM nginx:1.13-alpine
#WORKDIR /usr/src/app

COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 3000

This is how I had it before, and this was incorrect:

# linux distro
FROM node:14-alpine

# workdir inside the container
WORKDIR /usr/src/app

# copy these files to WORKDIR
COPY package.json .
COPY yarn.lock .

# Install all of the npm dependencies on the Docker image. 
RUN yarn install

# Copy everything from the folder which this Dockerfile is placed
# and unto the new containers WORKDIR
COPY . .

# Open port 3000
EXPOSE 3000

# Run the script "npm start" defined in package.json
# this will start the dev server and the project will be at the containers ip+ port.
CMD ["yarn", "start"]

If you make sure that you have your Dockerfile correct and you have "homepage", the paths should be correct and your react app should work at the subdomain.

As a side note, if you are having trouble with react routing, check your basepath, that will probably fix it for you. =)

like image 76
Ishiffman120 Avatar answered Oct 24 '22 01:10

Ishiffman120