I've been following this post on Medium to learn how to create and run a dotnet core console app in a docker container, and post to a dotnet core API in another container.
When I run the two applications side-by-side (without docker, i.e. just debugging in vscode), everything works OK - the console app can post to the API. However, when I run the applications in containers using docker-compose up --build
, I get an error when the application tries to post to the api:
Unhandled exception. System.AggregateException: One or more errors occurred. (The SSL connection could not be established, see inner exception.)
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
System.IO.IOException: The handshake failed due to an unexpected packet format.
Searching for solutions to this error hasn't helped much, and I feel that the problem may simply be connectivity between the two containers, but I've had no luck trying to resolve it.
My docker-compose
file is as follows:
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
My console app code (or at least the relevant part) is:
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}");
}
}
}
I wont post any of the API code, as I dont think any of it should be relevant, but please let me know if you think it would help.
If anyone has any idea on what the cause of this error is or how to resolve it, I'd appreciate the help.
Thought it would be useful to include the versions being used:
3.0.101
19.03.5, build 633a0ea838
Looks like I had mad a couple of fairly obvious mistakes, however they're not so obvious when you're completely new to Docker, like me.
The hostname to post to should be the name of the service, not the container.In my case, I had to change the console app to post to the name of the API service declared in the docker-compose file, publisher_api
.
Use HTTP instead of HTTPS. When I debugged the API locally, it launches with HTTPS by default. I assumed I would use HTTPS when running the container in docker, but this doesn't seem to work by default. Changing to HTTP resolved the issue (although this ideally will be a short-term solution).
So just for completeness, here's my updated code. Only the URL that the console app posts to had to change:
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}");
}
}
}