如何使用 NGINX 托管多个 Create-React-App 生产构建,每个都在一个单独的目录中(没有 Docker)

How to host multiple Create-React-App production builds with NGINX, each in a separate directory (without Docker)

我正在尝试找到一种方法来托管多个(目前是 2 个)React 应用程序,每个应用程序都是用 CRA 创建的。这两个应用程序都应该 运行 在单个 NGINX 实例之后,并且可以在单独的目录中访问:

app1 -> http://localhost/app1

app2 -> http://localhost/app2

像这样创建的 2 个 React 应用程序:

npx create-react-app app1
npx create-react-app app2

为了使用 NGINX 托管两个 React 应用程序,每个 CRA 应用程序 (npm run build) 的生产构建被复制到 NGINX 静态目录 /var/www/app[1|2]

# App1
npm run build
cp build/* /var/www/app1

# App2
npm run build
cp build/* /var/www/app2

这是设置 NGINX 以托管单个 CRA 应用程序的方式:

# /etc/nginx/conf.d/default.conf
server {
    listen 80;
    listen [::]:80;

    server_name localhost;

    location / {
        root /var/www/app1;
        index index.html;
    }
}

现在我正在尝试扩展此示例,以便两个 CRA 应用程序都由一个 NGINX 托管。

NGINX site.conf 和每个 React 应用程序本身需要进行哪些修改?

我将上面显示我的(不完整)示例的代码推送到 Github 以供参考:https://github.com/wolkenarchitekt/multiple-cra-apps-behind-nginx。 为简单起见,代码使用 docker-compose,但最终整个堆栈应该 运行 而没有 Docker,因此 运行ning 为每个单独的 Docker 服务React 应用程序不是一个选项。

为了 运行 两个 React 应用程序在同一个域但不同的子文件夹中,您应该只需要两个 location 块:

root /var/www;
location /app1/ {
        index index.html;
    }
location /app2/ {
        index index.html;
    }

React 应用程序中的必要更改通常包括:

  • 更改 package.json as described here
  • 中的 homepage 字段
  • (仅在使用 react-router 时适用,旧版本应该类似)将 BrowserRouterbasename 更改为您的子目录:<BrowserRouter basename='/app1'>

编辑:

检查你的 repo 之后(在你推送新分支之前)我刚刚让它与以下 Dockerfile 一起工作(对于开发来说更糟糕,因为每次代码更改都需要重建,我只是喜欢多阶段构建,这会更多适用于生产环境):

FROM node:16 as builder1
WORKDIR /var/app
COPY app1/package.json .
COPY app1/package-lock.json .
RUN npm i
COPY app1/public/ ./public
COPY app1/src/ ./src
RUN npm run build

FROM node:16 as builder2
WORKDIR /var/app
COPY app2/package.json .
COPY app2/package-lock.json .
RUN npm i
COPY app2/public/ ./public
COPY app2/src/ ./src
RUN npm run build


FROM nginx:mainline-alpine
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/site.conf /etc/nginx/conf.d/default.conf
COPY --from=builder1 /var/app/build/ /var/www/app1
COPY --from=builder2 /var/app/build/ /var/www/app2

以下 site.conf 对我有用:

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

    server_name localhost;
    root /var/www;

    location /app1 {
        index index.html;
    }
    location /app2 {
        index index.html;
    }
}

只好把homepage分别改成/app1/app2,把app2/App.js改成实际输出App2,然后

docker build . -t testreactmultiple:latest
docker run -it -p 3000:80 docker.io/library/testreactmultiple:latest  

我希望这可以帮助您重现在请求索引时出错但在请求 /app1/app2 时工作正常的工作容器。