联网 docker 容器上的 HttpClient 请求

HttpClient request on networked docker container

我是 docker 容器的新手,我 运行 遇到了以下问题。我正在开发一个向公开的 api 发出请求的网页。它们都发布在通过网络链接的不同容器上。 这是我的 docker-compose.yml 文件:

version: '2'

services:
  api:
    image: my/api
    networks:
      - api
    ports:
      - "8080:5000"    
    container_name: api  

  web:
    build:
      context: ./DockerWeb      
    networks:
      - api      
    ports:
      - "80:5000"    
    container_name: web

networks:    
  api:
    driver: bridge

我注意到如果我附加到容器 运行 我的网页我可以使用 ping api

ping api 容器没有任何问题

尝试对 api 容器进行任何 Web 服务调用时会出现问题。我正在尝试初始化一个 HttpClient 对象,但是必须将此类对象的 BaseAddress 属性 设置为有效的 Uri。

_client = new HttpClient();
_client.BaseAddress = new Uri(config.ApiUrl); //config.ApiUrl = "api"

这将引发以下错误

UriFormatException: Invalid URI: The format of the URI could not be determined.

有没有办法 a) 以不同的方式公开容器名称,或者 b) 在不需要使用 URI 的情况下调用 Web 服务? 我怎样才能做到这一点?

更新

我已经更新了 ApiUrl 以包含值 http:api:8080,但是现在我在执行调用时遇到异常

System.AggregateException: One or more errors occurred. (An error occurred while sending the request.) ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.CurlException: Couldn't connect to server

我也尝试过使用 wget

直接从我的 Web 容器调用 api 端点
wget http://api:8080/ 

但是我仍然收到错误消息:

Connecting to api (api)|172.24.0.4|:8080... failed: Connection refused

这可能是 API 配置错误吗?

api 只是主机名。 URI 将是 http://api:8080(或 https://api:someotherport,如果您设置 SSL/TLS。)

这里有2种交流方式:

容器 web > 容器 api

在这种情况下,确实,您可以只使用主机名 "api" 连接到您的 api。 如果您的 html 是在服务器端生成的,这就是您必须要做的。

Web 客户端 > 容器 api

但是我假设您正在使用某种 JavaScript 网络应用程序(Angular 或其他)。在那种情况下,html(和调用)不是从 Web 容器发出的,而是直接从您的 Web 浏览器发出的。

所以在那种情况下你必须使用 http://localhost:8080(我假设 Docker 在你的本地机器上是 运行)。

希望对你有帮助

内部端口用于 docker 网络内部的连接。所以在这种情况下,请求需要转到 http://api:5000