【问题标题】:Proxying API Requests in Docker Container running react app在运行反应应用程序的 Docker 容器中代理 API 请求
【发布时间】:2020-03-19 01:52:43
【问题描述】:

我正在一个 docker 容器中运行一个简单的 react 应用程序。在开发过程中,我使用package.json 中的代理密钥来指定我的后端 api url:"proxy": "http://localhost:5000"

当我在本地运行 npm start 时一切正常。但是,当我在 docker 容器内 npm start 时,它指向 "http://localhost:3000"。我也尝试手动设置代理,如下面的 Dockerfile 所示,但似乎没有任何效果:

FROM node:13-alpine
WORKDIR /app

# install dependencies
COPY package*.json ./
RUN npm install --silent

# copy source code
COPY src/ ./src/
COPY public/ ./public/

RUN npm config set proxy http://localhost:5000  # set manully
CMD ["npm", "start"]

是我做错了什么还是不可能?

【问题讨论】:

    标签: reactjs docker proxy


    【解决方案1】:

    您现在在 Docker 容器中运行您的 React 应用程序,因此您的“本地主机”不再是您的本地机器,而是容器。您需要将其代理到后端的 IP。您是否在另一个容器中运行 API?

    【讨论】:

    • 是的,api 正在一个单独的容器中运行
    【解决方案2】:

    在 docker 中运行应用程序时,您需要将端口设置为后端服务而不是 localhost。例如,检查以下 docker 容器及其服务。我们的前端运行在端口3000,后端运行在端口5000。因此,将 localhost 替换为 "proxy": "http://backend:5000"

    version: '3'
    
    services:
      backend:
        build: ./backend
        ports:
          - 5000:5000
      frontend:
        build: ./frontend
        ports:
          - 3000:3000
        links:
          - backend
        command: npm start
    
    

    【讨论】:

    • 嗨@Suman 你的回答似乎很有趣。在我的应用程序中尝试了您的答案,但没有奏效。以防万一你有时间帮助我。这是我昨天写的帖子的链接。 stackoverflow.com/questions/63136530/…谢谢
    • @Zenit 看来您已经收到了答案。如果没有,请告诉我,以便我为您查找!
    【解决方案3】:

    "proxy": "http://localhost:5000" 在开发阶段工作得非常好,因为 webpack DevServer 自己处理代理。一旦你部署了你的 React 应用程序,它就会停止运行。在尝试让我的容器化 React 应用程序与容器化 API 对话时,我遇到了同样的问题。我使用 Nginx 作为 Web 服务器来为 React 应用程序提供服务。我按照guide 将 Nginx 与 Docker 容器集成。这就是 nginx.conf 最初的样子:

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

    但是在我在这里和那里做了一些调整之后,我想出了这个配置(我会稍微谈谈 api 代表什么):

    server {
    
      listen 80;
    
      location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
      }
    
      location /api {
        resolver 127.0.0.11;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://api:8000;
      }
    
      error_page   500 502 503 504  /50x.html;
    
      location = /50x.html {
        root   /usr/share/nginx/html;
      }
    
    }
    
    

    发生了什么变化?我为 API 端点添加了一个根位置,因为它们都有一个公共前缀 /apiproxy_pass 属性允许我们将所有来自 /api 的请求代理到通过端口 8000 公开的后端。api 只是在 docker-compose.yaml 中定义的容器的名称。

    作为参考,这是我的 React 应用的 Dockerfile

    # build environment
    FROM node:15.2.1 as build
    WORKDIR /app
    COPY ./client ./
    RUN yarn
    RUN yarn build
    
    # production environment
    FROM nginx:stable-alpine
    COPY --from=build /app/build /usr/share/nginx/html
    COPY --from=build /app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    

    还有最重要的文件(docker-compose.yaml):

    version: "3.8"
    
    services:
      client:
        build:
          context: .
          dockerfile: client/Dockerfile
        container_name: $CLIENT_CONTAINER_NAME
        restart: unless-stopped
        env_file: .env
        ports:
          - "1337:80"
        networks:
          - my-network
        links:
          - api
      api:
        build:
          context: .
          dockerfile: server/Dockerfile
        container_name: $API_CONTAINER_NAME
        restart: unless-stopped
        env_file: .env
        ports:
          - "8000:8000"
        networks:
          - my-network
        links:
          - mongo
      mongo:
        image: mongo
        container_name: $DB_CONTAINER_NAME
        restart: unless-stopped
        env_file: .env
        environment:
          - MONGO_INITDB_ROOT_USERNAME=$MONGO_INITDB_ROOT_USERNAME
          - MONGO_INITDB_ROOT_PASSWORD=$MONGO_INITDB_ROOT_PASSWORD
          - DB_NAME=$DB_NAME
          - MONGO_HOSTNAME=$MONGO_HOSTNAME
        volumes:
          - ~/data/db:/data/db
        ports:
          - 27017:27017
        networks:
          - my-network
    
    networks:
      my-network:
        driver: bridge
    

    【讨论】:

      猜你喜欢
      • 2018-02-22
      • 2021-01-05
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多