【问题标题】:Proxying react app using nginx on docker-compose在 docker-compose 上使用 nginx 代理反应应用程序
【发布时间】:2020-05-15 08:26:46
【问题描述】:

我正在尝试使用 docker-compose 来运行 2 个容器 - 一个示例反应应用程序和一个 nginx 以充当反向代理。
我已经运行npx create-react-app react-app 来创建第一个容器,并将以下 Dockerfile 添加到文件夹 -

FROM node
RUN yarn global add serve
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn
COPY . ./
RUN yarn build
CMD serve -s build

然后我继续在./nginx下创建以下nginx配置文件 -

server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    location /react {
        proxy_pass http://react:5000;
    }
}

最后,我在项目的根目录中创建了这个docker-compose.yaml 文件 -

version: '3'
services:
  nginx: 
    image: nginx:latest
    container_name: production_nginx
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    ports:
      - 80:80
      - 443:443

  react:
    build: ./react-app
    container_name: react-app
    expose:
      - "5000"
    ports:
      - 5000:5000

然后我使用docker-compose up --build 启动我的堆栈,但是当我使用http://localhost/react 路径时,我的 nginx 访问日志中出现以下错误 -

eact-app | INFO: Accepting connections at http://localhost:5000
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:29 +0000] "GET /react HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 2020/01/29 18:24:29 [error] 7#7: *1 open() "/usr/share/nginx/html/static/css/main.d1b05096.chunk.css" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /static/css/main.d1b05096.chunk.css HTTP/1.1", host: "localhost", referrer: "http://localhost/react"
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:29 +0000] "GET /static/css/main.d1b05096.chunk.css HTTP/1.1" 404 555 "http://localhost/react" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:29 +0000] "GET /static/js/2.250dc4af.chunk.js HTTP/1.1" 404 555 "http://localhost/react" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:29 +0000] "GET /static/js/main.de4c6317.chunk.js HTTP/1.1" 404 555 "http://localhost/react" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 2020/01/29 18:24:29 [error] 7#7: *4 open() "/usr/share/nginx/html/static/js/2.250dc4af.chunk.js" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /static/js/2.250dc4af.chunk.js HTTP/1.1", host: "localhost", referrer: "http://localhost/react"
production_nginx | 2020/01/29 18:24:29 [error] 7#7: *3 open() "/usr/share/nginx/html/static/js/main.de4c6317.chunk.js" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /static/js/main.de4c6317.chunk.js HTTP/1.1", host: "localhost", referrer: "http://localhost/react"
production_nginx | 2020/01/29 18:24:29 [error] 7#7: *5 open() "/usr/share/nginx/html/manifest.json" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /manifest.json HTTP/1.1", host: "localhost", referrer: "http://localhost/react"
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:29 +0000] "GET /manifest.json HTTP/1.1" 404 555 "http://localhost/react" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 2020/01/29 18:24:34 [error] 7#7: *3 open() "/usr/share/nginx/html/static/js/2.250dc4af.chunk.js" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /static/js/2.250dc4af.chunk.js HTTP/1.1", host: "localhost", referrer: "http://localhost/react"
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:34 +0000] "GET /static/js/2.250dc4af.chunk.js HTTP/1.1" 404 555 "http://localhost/react" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 172.18.0.1 - - [29/Jan/2020:18:24:34 +0000] "GET /static/js/main.de4c6317.chunk.js HTTP/1.1" 404 555 "http://localhost/react" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36" "-"
production_nginx | 2020/01/29 18:24:34 [error] 7#7: *4 open() "/usr/share/nginx/html/static/js/main.de4c6317.chunk.js" failed (2: No such file or directory), client: 172.18.0.1, server: localhost, request: "GET /static/js/main.de4c6317.chunk.js HTTP/1.1", host: "localhost", referrer: "http://localhost/react"

在我看来,nginx 似乎正在 nginx 容器中寻找 Reacts 静态资产,但我不确定它为什么不将这些请求代理到反应容器。知道如何解决这个问题吗?

【问题讨论】:

    标签: reactjs docker nginx docker-compose reverse-proxy


    【解决方案1】:

    在找到this great blogpost 之后,我设法通过将 nginx 配置更改为这个来解决这个问题 -

    upstream backend {
        server react:5000;
    }
    
    server {
        listen 80;
        server_name localhost§
    
        root /usr/src/app;
    
        location / {
            try_files $uri @backend;
        }
    
        location @backend {
            proxy_pass http://backend;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # Following is necessary for Websocket support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
    

    【讨论】:

      【解决方案2】:

      我没有使用 nginx 反向代理到我的前端。仅将来自我的前端的请求连接到我的服务器。相反,您可以尝试直接通过 nginx 托管您的 react-app。这是我做到这一点的一种方法。

      我没有运行两个容器,而是在我的react-app 的根目录中设置了一个DockerfileDockerfile 对 react 应用程序进行生产构建,然后将其复制到 nginx 中,以托管在 nginx 配置中的 / 路由中。这就是那个文件的样子。

      # Frontend build based on Node.js
      FROM node:11.12.0-alpine as build-stage
      RUN mkdir -p /usr/src/app
      WORKDIR /usr/src/app
      ENV PATH /usr/src/app/node_modules/.bin:$PATH
      COPY package.json /usr/src/app/package.json
      RUN npm install
      RUN npm install react-scripts@latest -g
      COPY . /usr/src/app
      #RUN CI=true npm test
      RUN npm run build
      
      # Stage 1
      # Production build based on Nginx with artifacts from Stage 0
      FROM nginx:1.15.9-alpine
      COPY config/nginx.conf /etc/nginx/conf.d/default.conf
      COPY --from=build-stage /usr/src/app/build /usr/share/nginx/html
      EXPOSE 80
      CMD ["nginx", "-g", "daemon off;"]
      

      react-app 的根目录中,我还有一个config 目录。在该目录中,我有 nginx.conf 文件,看起来像这样。

      server {
      
          listen 80;
          server_name  localhost;
      
          location / {
              root   /usr/share/nginx/html;
              index  index.html index.htm;
              try_files $uri /index.html;                 
          }
      
          # redirect server error pages
      
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   /usr/share/nginx/html;
          }
      
      }
      

      由于在第一步中将前端构建复制到 nginx 中,它现在可以在它自己的文件系统中找到构建目录。之后,您可以在容器中构建和运行映像,一切都应该正确构建。我认为此时您所要做的就是将您的docker-compose.yml 文件移动到react-app 根目录,摆脱react 服务,将image: nginx:latest 更改为build: . 并运行docker-compose up -d。你也可以放弃compose 并通过运行docker build -t react-app 来使用docker,然后在构建之后,在react-app 目录的根目录中运行docker run -d -p 80:80 react-app。这是一种非常简单的入门方式,可能并不完全符合您的要求。不过希望对您有所帮助。

      【讨论】:

      • 感谢您的详尽解释。问题在于,这是本地尝试复制生产示例的努力,其中 nginx 必须从远程位置为资产和应用程序提供服务。我实际上是在等待答案时完成的,我现在将发布解决方案。
      • 哦,好吧。我很想看看你是怎么想出来的。
      猜你喜欢
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      • 2019-09-27
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多