简体   繁体   English

Nginx 反向代理多个 React 应用程序

[英]Nginx reverse proxy multiple react apps

dear stack overflow,亲爱的堆栈溢出,

I'm trying to configure an Nginx reverse proxy to serve two react apps based on the base URL of each under the same domain, below you will find the current configuration used in the projects.我正在尝试配置一个 Nginx 反向代理,以根据同一域下每个应用程序的基本 URL 为两个反应应用程序提供服务,您将在下面找到项目中使用的当前配置。

The current situation is that when browsing to the ADMIN URL (/admin/) the index.html file is loaded for every single request that is done by the browser, so all the assets are loaded as if they are the index.html , so my assumption is that the missing configuration is in one of the nginx.conf files?当前的情况是,当浏览到 ADMIN URL (/admin/) 时,会为浏览器完成的每个请求加载index.html文件,因此所有资产都像index.html一样加载,所以我的假设是缺少的配置在nginx.conf文件之一中?


Project Structure项目结构

  • NGINX (proxy) NGINX(代理)
    • NGINX - React APP (/) NGINX - React 应用程序 (/)
    • NGINX - React APP Admin (/admin) NGINX - React APP 管理员 (/admin)

Configuration配置

Docker Compose码头工人撰写

version: "3.7"

services:
  nginx:
    image: nginx:stable-alpine
    container_name: nginx
    ports:
      - 8000:80
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
  frontend:
    container_name: frontend
    build:
      context: ../frontend
      dockerfile: Dockerfile.prod
  frontend-admin:
    container_name: frontend-admin
    build:
      context: ../frontend-admin
      dockerfile: Dockerfile.prod

nginx.conf nginx.conf

http {

  server {
    listen                80;

    location /admin/ {
      proxy_pass          http://frontend-admin:80;
    }

    location / {
      proxy_pass          http://frontend:80;
    }

  }
}

REACT APPs反应应用

The files below are used in both projects, I have tried changing the ' location / ' from the admin project to ' location /admin/ ' but without any success.下面的文件在两个项目中都使用了,我尝试将 ' location / ' 从 admin 项目更改为 ' location /admin/ ' 但没有任何成功。

Dockerfile Dockerfile

# build environment
FROM node:14.16.1-alpine as build
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn
COPY . ./
RUN yarn build

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

nginx.conf nginx.conf

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

React APP反应应用

vite.config.js vite.config.js

// ...
export default defineConfig(({ mode }) => ({
  base: '/',
  // ...
}));

React APP Admin React APP 管理员

vite.config.js vite.config.js

// ...
export default defineConfig(({ mode }) => ({
  base: '/admin/',
  // ...
}));

What worked for me is to use rewrite on admin's location block so the downstream nginx would receive clean paths.对我有用的是在管理员的位置块上使用rewrite ,这样下游的 nginx 就会收到干净的路径。

After some modifications, the global config looks like this:经过一些修改,全局配置如下所示:

user nginx;

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;

  server {
    listen 80;

    location /admin {
      rewrite /admin(.*) /$1 break;
      proxy_pass http://frontend-admin:80;
    }

    location / {
      proxy_pass http://frontend:80;
    }
  }
}

While app configs look like this:虽然应用程序配置如下所示:

user nginx;

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;
  sendfile on;
  server {
    listen 80;

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

Then, requests are forwarded correctly to the admin nginx:然后,请求被正确转发到 nginx 管理员:

frontend-admin    | 172.21.0.4 - - [19/Jul/2021:14:35:02 +0000] "GET / HTTP/1.0" 200 362 "-" "curl/7.77.0"
nginx             | 172.21.0.1 - - [19/Jul/2021:14:35:02 +0000] "GET /admin HTTP/1.1" 200 362 "-" "curl/7.77.0"

Also couple of things to notice:还有几点需要注意:

  1. I had to include /etc/nginx/mime.types for all nginx to send the right Content-Types to the browser.我必须为所有 nginx 包含/etc/nginx/mime.types以将正确的 Content-Types 发送到浏览器。
  2. Instead of removing default.conf and adding nginx.conf to /etc/nginx/conf.d I directly replaced /etc/nginx/nginx.conf我没有删除default.conf并将nginx.conf添加到/etc/nginx/conf.d我直接替换了/etc/nginx/nginx.conf
  3. Used nginx:latest and node:14.16.1 for building, but alpine should work just fine使用nginx:latestnode:14.16.1进行构建,但 alpine 应该可以正常工作

docker-compose.yml docker-compose.yml

version: "3"

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - 8000:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
  frontend:
    container_name: frontend
    build:
      context: ./frontend
      dockerfile: ../Dockerfile.prod
  frontend-admin:
    container_name: frontend-admin
    build:
      context: ./frontend-admin
      dockerfile: ../Dockerfile.prod

Dockerfile.prod Dockerfile.prod

# build environment
FROM node:14.16.1 as build
WORKDIR /usr/src/app
COPY [ "package.json", "yarn.lock", "./" ]
RUN yarn install --frozen-lockfile
COPY . ./
RUN yarn build

# production environment
FROM nginx:latest

COPY --from=build /usr/src/app/dist /usr/share/nginx/html
COPY --from=build /usr/src/app/nginx.conf /etc/nginx/nginx.conf

I'm not sure if it would help but it worth a try:我不确定它是否会有所帮助,但值得一试:

  1. Your files for the admin app should be placed under /usr/share/nginx/html/admin directory of the frontend-admin container.您的 admin 应用程序文件应放在frontend-admin容器的/usr/share/nginx/html/admin目录下。

  2. Use the following nginx config for the admin app:将以下 nginx 配置用于管理应用程序:

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

better use sub domaines, this way you won't have such issue, below an example I use for jenkins:更好地使用子域,这样你就不会遇到这样的问题,下面是我用于詹金斯的例子:

server     {
    listen 80;
    listen [::]:80;

    server_name     jenkins.site;

    location / {
                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;
                include       /etc/nginx/mime.types;
                proxy_pass http://jenkins:8080;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM