Connection refused on API request between containers with docker compose

I’m developing a multi-container Docker application and I want a container to make an HTTP request to API of other container using Docker Compose. I’m getting Connection Refused error.

Both containers run ASP.NET Core 2.2. The IDE I’m using is Visual Studio 2017. I’m testing API calls with Postman.

Things I’ve tried:
:heavy_check_mark: Ports are exposed in Dockerfiles
:heavy_check_mark: Ports are declared in Docker Compose configuration
:heavy_check_mark: Network is declared in Docker Compose and containers are connected to it
:heavy_check_mark: Http request URI uses service name and not localhost or local IP address
:heavy_check_mark: Http request URI uses container port (80) and not host port
:heavy_check_mark: Firewall is disabled

Dockerfiles

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
...

Docker Compose configuration:

version: '3.4'

services:
  servicea:
...
ports:
  - "51841:80"
  - "44364:443"
networks:
  - local

  serviceb:
  ...
ports:
  - "65112:80"
  - "44359:443"
networks:
  - local

networks:
  local:
driver: bridge

serviceA controller action:

[Route("[action]")]
[HttpGet]
public IActionResult foo()
{
   HttpClient client = _clientFactory.CreateClient();

   var result = client.GetAsync("http://serviceb:80/api/bar").Result;
   var response = result.Content.ReadAsStringAsync().Result;

   return new OkObjectResult(response);
}

If I do an Http Get request to serviceA (with host port 51841) with Postman at http://localhost:51841/api/foo I’d like to get the response of serviceB’s Bar action.

But I’m getting Connection refused

Raw exception details:

System.Net.Http.HttpRequestException: Connection refused ---> System.Net.Sockets.SocketException: Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)

I am having a similar issue with nginx-proxy. The proxy works, and i can access the api and the ui separately from a client. But I cannot access the api from the ui.

I have two sites with subdomains: api .example. com and ui. example. com. I navigate to ui. example. com, and get the main page, but the call to api. example. com returns System.Net.Sockets.SocketException (111): Connection refused

Docker compose file:

version: '2'  

services:  

nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
  - '80:80'
  - '443:443'
volumes:
  - '/etc/nginx/vhost.d'
  - '/usr/share/nginx/html'
  - '/etc/nginx/certs:/etc/nginx/certs:ro' 
  - '/var/run/docker.sock:/tmp/docker.sock:ro'


letsencrypt-nginx-proxy:
container_name: letsencrypt-nginx-proxy
image: 'jrcs/letsencrypt-nginx-proxy-companion'
volumes:
  - '/etc/nginx/certs:/etc/nginx/certs'
  - '/var/run/docker.sock:/var/run/docker.sock:ro'
volumes_from:
  - nginx-proxy


 api.example.com:
environment:
  - LETSENCRYPT_HOST=api.example.com
  - LETSENCRYPT_EMAIL=development@scottrassbach.net
  - VIRTUAL_HOST=api.example.com
  - ASPNETCORE_ENVIRONMENT=Development
container_name: api.example.com
restart: always
image: srassbach/exampleapi:latest
expose: 
  - 80
  - 443


ui.example.com:
environment:
  - LETSENCRYPT_HOST=office.example.com
  - LETSENCRYPT_EMAIL=development@scottrassbach.net
  - VIRTUAL_HOST=office.example.com
  - ASPNETCORE_ENVIRONMENT=Development
restart: always
container_name: office.example.com
image: srassbach/example_ui:latest
expose:
  - 80
  - 443


www.example.com:
environment:
  - LETSENCRYPT_HOST=www.example.com
  - LETSENCRYPT_EMAIL=development@scottrassbach.net
  - VIRTUAL_HOST=www.example.com
  - ASPNETCORE_ENVIRONMENT=Production
restart: always
container_name: www.example.com
image: srassbach/example_landing:latest
expose:
  - 80


networks:  

default:
    external:
      name: nginx-net