404错误Docker + Nginx Reverse Proxy + React w/ Webpack

n6lpvg4x  于 2024-01-06  发布在  Docker
关注(0)|答案(1)|浏览(89)

我已经搜索并尝试了许多解决方案,以便在Docker中的Node + React(使用Webpack服务)应用程序中直接导航。我的React应用程序与大多数应用程序一样,使用BrowserRouter来导航页面。当直接导航到localhost:3050/SomePage时,经常遇到404问题,因为Nginx不知道如何处理该路由。
通用的解决方案似乎是将构建工件复制到**/usr/share/nginx/html**,这样我就可以利用try_files指令回退到我的index.html。
在我的docker构建过程中一定有问题,因为我指定将我的React工件(dist,带Webpack)复制到我的nginx/html文件夹。
除了解决这个问题之外,在本地工作时,什么是生产就绪以及开发人员友好的最佳方法?我不应该使用Webpack-CLI吗?
编辑:看起来我被Docker的层缓存烧伤了。我正在回溯我的步骤并在没有缓存的情况下重建,但到目前为止仍然无法让以下工作正常。
Nginx default.conf:

upstream client {
  server client:3000;
}

upstream api {
  server api:3001;
}

server {
  listen 80;

  location / {
      proxy_pass http://client;
      # root   /usr/share/nginx/html;
      # index  index.html index.htm;
      try_files $uri $uri/ /index.html;
  }

  location /sockjs-node {
      proxy_pass http://client;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
  }
  
  location /api {
      rewrite /api/(.*) /$1 break;
      proxy_pass http://api;
  }
}

字符串
Nginx Dockerfile:

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf


Client partial package.json:

"scripts": {
    "start": "webpack serve --config webpack.config.js --mode development",
    "build": "webpack --config webpack.config.js --mode development"
....

  "devDependencies": {
    "webpack-cli": "^5.1.4"
  }


客户端dockerfile(尝试1)

FROM node:alpine

# Set NODE_ENV to 'production' by default
ENV NODE_ENV=development

WORKDIR /app
COPY package.json ./
COPY package-lock.json ./

COPY ./ ./
RUN npm i
CMD ["npm", "run", "start"]


客户端dockerfile(尝试2)

# Stage 0: Build React app
FROM node:alpine as build-stage

# Set NODE_ENV to 'production' by default
ENV NODE_ENV=development

WORKDIR /app
COPY package*.json ./

# Install app dependencies
RUN npm install webpack-cli && \
    npm install

COPY ./ ./
RUN npm run build

# Stage 1: Final image
FROM nginx
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY --from=build-stage ../nginx/default.conf /etc/nginx/conf.d/default.conf


服务器Dockerfile:

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
CMD ["npm", "run", "dev"]


docker-compose.yml:

version: '3.8'

services:
  nginx:
    depends_on:
      - api
      - client
    restart: always
    build:
      dockerfile: Dockerfile
      context: ./nginx
    ports:
      - "3050:80"

  api:
    build:
      dockerfile: Dockerfile
      context: "./server"
    volumes:
      - /app/node_modules
      - ./server:/app
    env_file:
      - ./server/keys/dev.env

  client:
    stdin_open: true
    environment:
      - CHOKIDAR_USEPOLLING=true
      - NODE_ENV=development
    build:
      dockerfile: Dockerfile
      context: ./client
    volumes:
      - /app/node_modules
      - ./client:/app


我试着调整了几个迭代的解决方案:
React-router and nginxhttps://gist.github.com/tkc/c400263987f1a626e6d9d348b7379cafSet up nginx proxy for react applicationNginx and Create React App (with React Router) full routes not working

c3frrgcw

c3frrgcw1#

我通过使用单独的脚本来启动我的开发Docker环境与prod来解决这些问题。

  • 这可能不是生产中的最佳方法,如果不是,我想听听我如何才能实现这一点。*

在prod中,我将使用多阶段构建来将我的React应用工件复制到Nginx服务器中。
使用更简单的配置:

## client/default.conf

server {
  listen 80;

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

字符串
这也需要主nginx容器将请求代理到端口80。

## nginx/dev.conf
upstream client {
  server client: 80;
}
..... Rest remains the same
}


如果在dev中,webpack将服务于前端,这意味着nginx配置需要代理到端口3000:

## nginx/prod.conf
upstream client {
  server client:3000;
}


构建过程在dev和prod中也会有所不同,区别在于两个Dockerfile:

## client/devDockerfile
FROM node:alpine

WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm install webpack-cli && \
    npm install
CMD ["npm", "run", "start"]
## client/Dockerfile
# Stage 0: Build React app
FROM node:alpine as build-stage

# Set NODE_ENV to 'production' by default
ENV NODE_ENV=development

WORKDIR /app
COPY package*.json ./

# Install app dependencies
RUN npm install webpack-cli && \
    npm install

COPY ./ ./
RUN npm run build

# Stage 1: Final image
FROM nginx
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY ./default.conf /etc/nginx/conf.d/default.conf

现在我需要为开发环境覆盖docker-compose.yml。

version: '3.8'

services:
  client:
    build:
      dockerfile: devDockerfile
      context: ./client
    environment:
      - NODE_ENV=development
    ports:
      - "3000:3000"  # Expose the development server port during development


把所有这些放在一起,我现在可以使用这些脚本在dev和prod中避免404:

"scripts": {
    "docker:start": "npm run docker:check || npm run docker:compose",
    "docker:start:dev": "npm run docker:check || npm run docker:compose:dev",
    "docker:check": "docker inspect nginx api client > /dev/null 2>&1",
    "docker:compose": "docker-compose up docker-compose.yml -f -d",
    "docker:compose:dev": "docker-compose -f docker-compose.yml -f docker-compose.override.yml up",
    "docker:build": "docker-compose build --no-cache",
    "docker:build:dev": "docker-compose -f docker-compose.yml -f docker-compose.override.yml build --build-arg NODE_ENV=development --no-cache"
  }


请注意,我还更新了我的webpack.js.js文件,以允许在404时回退:

devServer: {
    port: 3000, 
    hot: true,
    historyApiFallback: true,
    allowedHosts: ["all"],
    proxy: {
      "/api": {
        target: "http://localhost:3001",
        changeOrigin: true,
        secure: false,
      },
    },
  },

相关问题