在运行 react 应用程序的 Docker 容器中代理 API 请求

Joh*_*etz 2 proxy docker reactjs

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

当我在npm start本地运行时,一切正常。但是,当我npm start在 docker 容器中时,它指向"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"]
Run Code Online (Sandbox Code Playgroud)

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

Sum*_*rel 8

在 docker 中运行应用程序时,您需要将端口设置为后端服务而不是 localhost。例如,检查以下 docker 容器及其服务。我们的前端在 port 中3000运行,后端在 port 中运行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

Run Code Online (Sandbox Code Playgroud)


Tai*_*yev 7

"proxy": "http://localhost:5000"在开发阶段工作得很好,因为 webpack DevServer 自己处理代理。一旦部署了 React 应用程序,它就会停止运行。当我尝试让我的容器化 React 应用程序与容器化 API 对话时,我也遇到了同样的问题。我使用 Nginx 作为 Web 服务器来为 React 应用程序提供服务。我按照本指南将 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;
  }

}
Run Code Online (Sandbox Code Playgroud)

但在我到处做了一些调整之后,我想出了这个配置(我将稍后讨论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;
  }

}

Run Code Online (Sandbox Code Playgroud)

发生了什么变化?我为 API 端点添加了根位置,因为它们都有一个共同的前缀/api。该属性让我们可以代理所有发送到通过端口 8000 公开的后端的proxy_pass请求。它只是./apiapidocker-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;"]
Run Code Online (Sandbox Code Playgroud)

以及最重要的文件(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
Run Code Online (Sandbox Code Playgroud)