在 docker-compose 服务之间通信时遇到问题

Having trouble communicating between docker-compose services

我有以下 docker-compose 文件:

version: "3"

services:
  scraper-api:
    build: ./ATPScraper
    volumes:
      - ./ATPScraper:/usr/src/app
    ports:
      - "5000:80"
  test-app:
    build: ./test-app
    volumes:
      - "./test-app:/app"
      - "/app/node_modules"
    ports:
      - "3001:3000"
    environment:
      - NODE_ENV=development
    depends_on:
      - scraper-api

构建以下 Dockerfile 的:

scraper-api(一个pythonflask申请):

FROM python:3.7.3-alpine

WORKDIR /usr/src/app

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "./app.py"]

test-app(针对api的测试react申请):

# base image
FROM node:12.2.0-alpine

# set working directory
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:/app/src/node_modules/.bin:$PATH

# install and cache app dependencies
COPY package.json /app/package.json
RUN npm install --silent
RUN npm install react-scripts@3.0.1 -g --silent
RUN npm install axios -g

# start app
CMD ["npm", "start"]

诚然,我是 Docker 网络方面的新手,但我正在尝试让 react 应用程序与 scraper-api 进行通信。例如,scraper-api 具有以下端点:/api/top_10。我尝试了以下 url 的各种排列: http://scraper-api:80/api/test_api。 None 他们一直在为我工作。

我一直在网上搜索,但找不到真正的解决方案。

附带说明:当 docker-compose.yml 中未指定网络时,将为您创建默认网络,名称如下 [dir location of docker_compose.yml]_default。例如,如果 docker_compose.yml 在 app 文件夹中。该网络将被命名为 app_default.

现在,在这个网络中,可以通过容器的服务名称访问容器。所以 scraper-api 主机应该解析到正确的容器。

可能是您使用了错误的端点URL。在问题中,您提到 /api/top_10 作为端点,但要测试的 URL 是 http://scraper-api:80/api/test_api,这是不一致的。

此外,您可能混淆了 docker-compose.yml 中 scraper-api 服务的端口顺序:

ports:
   - "5000:80"

5000 暴露给 docker 为 运行 的主机。 80 是内部应用程序端口。通常情况下,flask 应用程序正在监听 5000,所以我想你可能想说:

ports:
   - "80:5000"

在这种情况下,您必须在容器之间使用 :5000 作为 URL 中的目标端口:例如 http://scraper-api:5000(当然是 + 端点后缀)。

要检查连接性,您可能需要 bash 进入客户端容器,查看是否正在连接:

docker-compose exec test-app bash
wget http://scraper-api
wget http://scraper-api:5000

等等

如果您收到响应,则说明您已连接,只需要找出正确的端点 URL。

React 应用程序在最终用户的浏览器中运行,它根本不知道这个 "Docker" 东西存在,也不知道任何 Docker Compose 网络设置。对于碰巧由 Docker 托管的浏览器应用程序,需要将它们配置为使用 主机的 DNS 名称或 IP 地址,以及 [=19] 的已发布端口=] 服务.

一个常见的设置(Docker 或其他)是将浏览器应用程序和 back-end 应用程序置于反向代理之后。在这种情况下,您可以使用不带主机名的相对 URL,例如 /api/...,它们将被解释为 "the same host and port",从而完全绕过这个问题。