reactjs - Nginx 反向代理多个 React 应用

标签 reactjs nginx

亲爱的堆栈溢出,

我正在尝试配置一个 Nginx 反向代理,以根据同一域下每个应用程序的基本 URL 为两个 React 应用程序提供服务,您将在下面找到项目中使用的当前配置。

目前的情况是,当浏览到 ADMIN URL (/admin/) 时,index.html 文件会为浏览器完成的每个请求加载,因此会加载所有 Assets 好像它们是 index.html,所以我假设缺少的配置在 nginx.conf 文件之一中?


项目结构

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

配置

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

http {

  server {
    listen                80;

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

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

  }
}

REACT 应用程序

以下文件在两个项目中都有使用,我尝试将管理项目中的 'location/' 更改为 'location/admin/' 但没有成功.

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

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

React 应用

vite.config.js

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

React 应用管理

vite.config.js

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

最佳答案

对我有用的是在管理员的位置 block 上使用 rewrite,这样下游的 nginx 就会收到干净的路径。

经过一些修改后,全局配置如下所示:

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;
    }
  }
}

虽然应用配置如下所示:

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;
    }
  }
}

然后,请求被正确转发给管理员 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"

还有两点需要注意:

  1. 我必须为所有 nginx 添加 /etc/nginx/mime.types 以将正确的内容类型发送到浏览器。
  2. 我没有删除 default.conf 并将 nginx.conf 添加到 /etc/nginx/conf.d 我直接替换了 /etc/nginx/nginx.conf
  3. 使用 nginx:latestnode:14.16.1 进行构建,但 alpine 应该可以正常工作

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

# 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

关于reactjs - Nginx 反向代理多个 React 应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68432376/

相关文章:

laravel - Laradock 404 未找到带有存储符号链接(symbolic link)的文件

nginx - 用于 kubernetes 的 Ingress-nginx 用于Vault。怀疑缺乏成功的健康检查

javascript - 在不使用 Promise.all 和 Promise.resolve 的情况下在 JS 中的 promise 之间传递中间数据

javascript - 如何使用 JavaScript 中的 moment 将 GMT 转换为本地时间?

javascript - 导入和作为 props 传递哪个更有效?

python - 将 GeoIP 模块与 Nginx 和 UWSGI 结合使用

Nginx 只允许 root 和 api 位置

javascript - 尝试在 React.js 中从另一个图像服务器(akamai)获取图像

javascript - 在 Javascript 中读取 Synchronos 文件

python - NGINX、uWSGI 和 Flask 未运行子进程