Request between containers in asp.net core

Docker version

Client: Docker Engine - Community
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        6247962
 Built:             Sun Feb 10 04:12:31 2019
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       6247962
  Built:            Sun Feb 10 04:13:06 2019
  OS/Arch:          linux/amd64
  Experimental:     false

System info:

OS name:                          Microsoft Windows 10 Pro
OS Version:                   	  10.0.17134 Н/Д построение 17134
Изготовитель ОС:                  Microsoft Corporation
Build OS:                        Multiprocessor Free
Product code:                     00331-10000-00001-AA119
Изготовитель системы:             Gigabyte Technology Co., Ltd.
System model:                     B360M-D3H
System type:                      x64-based PC

Hi all. I’m new to docker. I have a project on asp.net core. It contains 4 projects: 3 microservices and 1 mvc. I configured docker compose in Visual Studio. Everything builds and run greate. Problem is that microservices can’t connect to each other. This is my compose file:
version: ‘3.4’

services:
  identity:
	image:  ${DOCKER_REGISTRY}identity
	build:
	  context: .
	  dockerfile: src/Services/Identity/IdentityService/Dockerfile
	networks:
	  - backend

  children:
	image:  ${DOCKER_REGISTRY}children
	build:
	  context: .
	  dockerfile: src/Services/Children/Children.API/Dockerfile
	depends_on:
	  - identity
	networks:
	  - backend

  report:
	image:  ${DOCKER_REGISTRY}report
	build:
	  context: .
	  dockerfile: src/Services/Report/Report.API/Dockerfile
	depends_on:
	  - identity
	  - children
	networks:
	  - backend
	links:
	  - "children:children"

  webmvc:
	image:  ${DOCKER_REGISTRY}webmvc
	build:
	  context: .
	  dockerfile: src/Web Apps/WebMVC/Dockerfile
	depends_on:
	  - identity
	  - children
	  - report
	networks:
	  - backend

networks:
  backend:
	driver: bridge

And docker-compose.override.yml file

version: '3.4'

services:
  webmvc:
	environment:
	  - ASPNETCORE_ENVIRONMENT=Development
	  - ASPNETCORE_URLS=https://*:443;http://*:80
	  - ASPNETCORE_HTTPS_PORT=44365
	ports:
	  - "50298:80"
	  - "44365:443"
	volumes:
	  - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
	  - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
  children:
	environment:
	  - ASPNETCORE_ENVIRONMENT=Development
	  - ASPNETCORE_URLS=https://*:443;http://*:80
	  - ASPNETCORE_HTTPS_PORT=44395
	ports:
	  - "50879:80"
	  - "44395:443"
	volumes:
	  - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
	  - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

  identity:
	environment:
	  - ASPNETCORE_ENVIRONMENT=Development
	  - ASPNETCORE_URLS=https://*:443;http://*:80
	  - ASPNETCORE_HTTPS_PORT=44328
	ports:
	  - "55738:80"
	  - "44328:443"
	volumes:
	  - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
	  - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

  report:
	environment:
	  - ASPNETCORE_ENVIRONMENT=Development
	  - ASPNETCORE_URLS=https://*:443;http://*:80
	  - ASPNETCORE_HTTPS_PORT=44385
	ports:
	  - "50389:80"
	  - "44385:443"
	volumes:
	  - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
	  - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

Below code which send request:

public async Task<IEnumerable<Child>> GetChildren()
{
	var uri = Infrastructure.API.Children.GetAll(_childrenByPassUrl);

	//temporary hard coded URI
	uri = "http://servicescoreexample_children_1:80/api/children";

	var responseString = await _apiClient.GetStringAsync(uri);

	return string.IsNullOrEmpty(responseString) 
		? Enumerable.Empty<Child>()
		: JsonConvert.DeserializeObject<IEnumerable<Child>>(responseString);
}

Solution (and directory too) are named ServicesCoreExample.

Firstly I think that containers aren’t in one network, so I added a “backend” bridge. When I run docker-compose up and inspect network all containers places in one network.

I tried to set container_name in compose file and to add links. Nothing helps me.

The best result that I got:

report_1    |       Request starting HTTP/1.1 GET https://localhost:44385/api/children
report_1    | info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
report_1    |       Route matched with {action = "Get", controller = "Children"}. Executing action Report.API.Controllers.ChildrenController.Get (Report.API)
report_1    | info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
report_1    |       Executing action method Report.API.Controllers.ChildrenController.Get (Report.API) - Validation state: Valid
report_1    | info: System.Net.Http.HttpClient.IChildrenService.LogicalHandler[100]
report_1    |       Start processing HTTP request GET http://servicescoreexample_children_1/api/children
report_1    | info: System.Net.Http.HttpClient.IChildrenService.ClientHandler[100]
report_1    |       Sending HTTP request GET http://servicescoreexample_children_1/api/children
children_1  | info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
children_1  |       Request starting HTTP/1.1 GET http://servicescoreexample_children_1/api/children
children_1  | info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
children_1  |       Request finished in 16.0708ms 307
report_1    | info: System.Net.Http.HttpClient.IChildrenService.ClientHandler[100]
report_1    |       Sending HTTP request GET https://servicescoreexample_children_1:44395/api/children
report_1    | info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
report_1    |       Executed action method Report.API.Controllers.ChildrenController.Get (Report.API), returned result Microsoft.AspNetCore.Mvc.BadRequestObjectResult in 6427.9024ms.

It seems like request on http port was accepted but api return BadRequestObjectResult. When all projects run in IIS or just as asp.net core application all is good.

Any suggestions? I just wanted to use docker and comunicate between my services via https :sob:

1 Like

Ok. It seems like I found a reason. Problem was in https. I haven’t certificate or something like that. So now just for development I added an HttpHandler.

services.AddHttpClient<IChildrenService, ChildrenService>()
    .ConfigurePrimaryHttpMessageHandler(()=> GetHandler(env))

static HttpClientHandler GetHandler(IHostingEnvironment env)
{
	if (env.IsDevelopment())
	{
		return new HttpClientHandler
		{
			ServerCertificateCustomValidationCallback = (req, cert, chain, sslPolicy) => true,
		};
	}
	else
	{
		return null;
	}
}

I don’t know how it will work not in Development. Maybe it will be helpfull for somebody else.

2 Likes