联网 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
我是 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
尝试对 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