簡體   English   中英

在運行 React 應用程序的 Docker 容器中代理 API 請求

[英]Proxying API Requests in Docker Container running react app

我正在 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"]

我做錯了什么還是不可能?

在 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

"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;
  }

}

但是在我在這里和那里做了一些調整之后,我想出了這個配置(稍后我將討論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 端點添加了一個根位置,因為它們都有一個公共前綴/api proxy_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

您現在正在Docker容器中運行React應用,因此您的“ localhost”不再是您的本地計算機,而是該容器。 您需要將其代理到后端的IP。 您是否在另一個容器中運行API?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM