将API请求从一个Docker容器发布到另一个

时间:2019-11-28 22:32:34

标签: docker .net-core docker-compose

我一直关注this post on Medium,以学习如何在Docker容器中创建和运行dotnet核心控制台应用程序,以及如何在另一个容器中发布到dotnet核心API。

当我并排运行两个应用程序(没有docker,即仅在vscode中调试)时,一切正常,控制台应用程序可以发布到API。但是,当我使用docker-compose up --build在容器中运行应用程序时,当应用程序尝试发布到api时会出现错误:

  

未处理的异常。 System.AggregateException:发生一个或多个错误。 (无法建立SSL连接,请参阅内部异常。)

     

System.Net.Http.HttpRequestException:无法建立SSL连接,请参阅内部异常。

     

System.IO.IOException:由于意外的数据包格式,握手失败。

寻找该错误的解决方案并没有多大帮助,我觉得问题可能仅仅是两个容器之间的连通性,但是我没有运气去解决它。

我的docker-compose文件如下:

version: '3.4'

services:
  publisher_api: 
    image: my_publisher_api:latest
    container_name: my_publisher_api_container
    build: 
      context: ./publisher_api
      dockerfile: Dockerfile

  worker:
    image: my_worker
    container_name: my_worker_container
    depends_on: 
      - "publisher_api"
    build:
      context: ./worker
      dockerfile: Dockerfile

我的控制台应用程序代码(或至少相关部分)是:

public static async Task PostMessage(object postData)
{
    var json = JsonConvert.SerializeObject(postData);
    var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");

    using (var httpClientHandler = new HttpClientHandler())
    {
        httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
        using (var client = new HttpClient(httpClientHandler))
        {
            var result = await client.PostAsync("https://my_publisher_api_container:80/values", content);
            string resultContent = await result.Content.ReadAsStringAsync();
            Console.WriteLine($"Server returned {resultContent}");
        }
    }
}

我不会发布任何API代码,因为我认为其中任何一个都不相关,但是如果您认为有帮助,请告诉我。

如果有人对导致此错误的原因或解决方法有任何了解,我将非常感谢您的帮助。

编辑

认为包括正在使用的版本会很有用:

  • dotnet核心:3.0.101
  • docker:19.03.5, build 633a0ea838

1 个答案:

答案 0 :(得分:0)

看起来我犯了两个相当明显的错误,但是当您像我一样完全不熟悉Docker时,这些错误并不那么明显。

  1. 要发布的主机名应该是服务的名称,不是容器的 。在我的情况下,我不得不更改控制台应用程序以将其发布为API服务的名称在docker-compose文件publisher_api中声明。

  2. 使用HTTP代替HTTPS。当我在本地调试API时,默认情况下会使用HTTPS启动。我以为在docker中运行容器时会使用HTTPS,但是默认情况下这似乎不起作用。更改为HTTP可以解决此问题(尽管理想情况下这是一个短期解决方案)。

因此,为了完整起见,这是我更新的代码。只需更改控制台应用程序发布到的URL:

public static async Task PostMessage(object postData)
{
    var json = JsonConvert.SerializeObject(postData);
    var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");

    using (var httpClientHandler = new HttpClientHandler())
    {
        httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
        using (var client = new HttpClient(httpClientHandler))
        {
            var result = await client.PostAsync("http://publisher_api80/values", content);
            string resultContent = await result.Content.ReadAsStringAsync();
            Console.WriteLine($"Server returned {resultContent}");
        }
    }
}