Rohith Poyyeri
Rohith Poyyeri

Reputation: 133

Docker container communication in .NET Core

I have two .NET Core3 API's. One acts as an API and other as BFF. Docker file and docker-compose of API as follows exposed in 5000:

version: "3.8"
services:
  api:
    container_name: api
    build: 
      context: ./TSTMaxAPI
    image: tstmaxapi:latest
    ports:
      - "5000:443"
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=Admin.123
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro

Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 as base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as build
WORKDIR /src
COPY ["TSTMaxAPI.csproj", "./"]
RUN dotnet restore "./TSTMaxAPI.csproj"
COPY . .
RUN dotnet build "TSTMaxAPI.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "TSTMaxAPI.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TSTMaxAPI.dll"]

When I run docker-compose, I can access https://localhost:5000/weatherforecast I can access https://localhost:5000/health Seems OK

Now for the BFF exposed at 4000

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 as base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as build
WORKDIR /src
COPY ["TSTMaxBFF.csproj", "./"]
RUN dotnet restore "./TSTMaxBFF.csproj"
COPY . .
RUN dotnet build "TSTMaxBFF.csproj" -c Release -o /app

FROM build AS publish
RUN dotnet publish "TSTMaxBFF.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TSTMaxBFF.dll"]

And docker-compose

version: "3.8"
networks:
  tst_network:
services:
  bff:
    container_name: bff
    build: 
      context: ./TSTMaxBff
    image: tstmaxbff:latest
    restart: on-failure 
    ports:
      - 4000:443
    environment:
      - API_HOST=https://api:5000
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=Admin.123
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro
    networks:
      - tst_network
    depends_on:
      - api

  api:
    container_name: api
    image: tstmaxapi:latest   
    restart: on-failure  
    ports:
      - 5000:443
    networks:
      - tst_network

Now when I run docker-compose here, looks like both BFF and API containers are spinning up.

I can access https://localhost:4000/health However, I can't access https://localhost:5000/weatherforecast I can't access https://localhost:5000/health and https://localhost:4000/weatherforecast, which calls API, relevant code as below

private static string API_URL = Environment.GetEnvironmentVariable("API_HOST");
private static string API_ENDPOINT = API_URL + "/weatherforecast";
var response = await _client.GetStringAsync(API_ENDPOINT);

And getting the following error

SocketException: Connection refused
System.Net.Http.ConnectHelper.ConnectAsync(string host, int port, CancellationToken cancellationToken)

HttpRequestException: Connection refused
System.Net.Http.ConnectHelper.ConnectAsync(string host, int port, CancellationToken cancellationToken)

Error output

docker ps output

docker ps

I need these 2 containers to talk to each other in dev mode as well as in production mode. Any help is appreciated. Thanks

Upvotes: 0

Views: 2356

Answers (2)

Rohith Poyyeri
Rohith Poyyeri

Reputation: 133

Fixed it as there was missing certificate. Here is the final docker-compose file in case someone finds it helpful

version: "3.8"

services:
  bff:
    container_name: bff
    build: 
      context: ./Bff
    image: bff:latest
    restart: on-failure 
    ports:
      - 4000:443
    environment:
      - API_HOST=https://api
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=Admin.123
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro
    depends_on:
      - api

  api:
    container_name: api
    image: api:latest   
    restart: on-failure  
    ports:
      - 5000:443
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=Admin.123
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro

Upvotes: 1

Adiii
Adiii

Reputation: 59916

First thing, service to service communication use container port, not the publish port.

    environment:
      - API_HOST=https://api:5000

as API container port is 443

    ports:
      - 5000:443

so the API host should be

    environment:
      - API_HOST=https://api:443

also By default, Docker runs through a non-networked UNIX socket and communicate using an HTTP socket.

Why you are enable HTTP inside the container? this should be done using Nginx or another Load balancer.

If the above did not work then you can also try with HTTP

API_HOST=http://api:443

Upvotes: 1

Related Questions