首页 > 解决方案 > Docker Swarm:React 前端无法连接到 Kong API 网关

问题描述

我正在开发一个使用微服务的项目,我正在尝试将我在 React 中的前端与通过 Kong API 网关提供服务的后端连接起来。问题是每当我向服务器发送请求时,都会收到错误消息net::ERR_NAME_NOT_RESOLVED。前端服务与 API Gateway 服务在同一网络中运行,但显然 DNS 解析不起作用。

这就是我构建 React 前端 Docker 映像的方式:

FROM node:13.12.0-alpine

WORKDIR /app

ENV PATH /app/node_modules/.bin:$PATH

COPY package.json ./
COPY package-lock.json ./
RUN npm install --silent
RUN npm install react-scripts@3.4.1 -g --silent

COPY . ./

CMD ["npm", "start"]

这就是我从前端发送请求的方式:

handleLogin(event) {
    event.preventDefault();
    console.log("Log in " + JSON.stringify(this.state.loginForm));
    axios.post(`http://${process.env.API_URL}:${process.env.API_PORT}/api/users/login`, this.state.loginForm)
      .then((response) => {
        const model: LoginModel = response.data;
        this.handleLoginResponse(model);
      })
      .catch((errors) => alert(`Error sending login request to server: ${errors}`));
  }

这是我用于 Docker Swarm 部署的 stack.yml 配置文件:

version: "3.8"

services:
  kong:
    image: kong:latest
    hostname: kong
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong-plugins.yml
      KONG_PROXY_ACCESS_LOG: /dev/stdout
      KONG_ADMIN_ACCESS_LOG: /dev/stdout
      KONG_PROXY_ERROR_LOG: /dev/stderr
      KONG_ADMIN_ERROR_LOG: /dev/stderr
      KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl
    deploy:
      placement:
        constraints: [node.role == manager]
    ports:
      - 8000:8000
      - 8443:8443
      - 8001:8001
      - 8444:8444
    volumes:
      - ../../Kong:/usr/local/kong/declarative
    networks:
      - frontend-network
      - internal
      - logging

  frontend-service:
    image: virusx98/frontend
    environment:
      API_URL: kong
      API_PORT: 8000
    ports:
      - "3001:3000"
    networks:
      - frontend-network

  [...] /* other services */

  
volumes:
  [...] /* volumes for other services */

networks:
  frontend-network:
  [...] /* other networks */

secrets:
  [...] /* secrets for other services */

堆栈在后端​​完美运行。如果我使用 Postman 发送请求,它们会到达后端服务并返回结果。但是,如果我从前端发送请求,则会引发上述错误,即使两个服务都放在同一个网络中并且 DNS 解析应该可以工作。React 服务可以正确读取环境变量,但它说它无法解析 hostname kong。我在这里想念什么?

标签: reactjsdockerdocker-swarmkong

解决方案


根据评论编辑

您无法访问 API 的原因是 Node 进程未发送请求。您的浏览器正在发送请求。API 必须可以从您(和其他所有人的)浏览器访问。在这种情况下,您的 URL 需要localhost:8000在您的 javascript 中,以便您的浏览器能够访问kong容器。

原始答案(仅对环境变量有帮助)

react-scripts 只会从 Node.js 加载几个环境变量。从他们的文档中:

注意:您必须创建以 REACT_APP_ 开头的自定义环境变量。除了 NODE_ENV 之外的任何其他变量都将被忽略,以避免在机器上意外暴露可能具有相同名称的私钥。

这意味着您必须docker-compose.yml像这样更新:

    environment: 
      REACT_APP_API_URL: kong
      REACT_APP_API_PORT: 8000

这样做,并console.log(process.env)产生:

{
  "NODE_ENV": "development",
  "PUBLIC_URL": "",
  "FAST_REFRESH": true,
  "REACT_APP_API_PORT": "8000",
  "REACT_APP_API_URL": "kong"
}

话虽如此,您不应将 react-scripts start 用于生产目的。始终进行生产构建。您应该改为将.env文件添加到项目中,以便将这些变量注入构建中。您将无法通过 docker-compose 注入它们。

参考:


推荐阅读