'Dockerized API returns socket hang up via Postman

I've created simple RestAPI in .net core 5.0 - it has only one job, return StatusCode 200 or 500:

[ApiController]
[Route("api")]
public class HomeController : Controller
{
    [HttpGet]
    [Route("checktrue")]
    public IActionResult HealthCheckTrue()
    {
        return Ok();
    }

    [HttpGet]
    [Route("checkfalse")]
    public IActionResult HealthCheckFalse()
    {
        return StatusCode(500);
    }
}

When im building it locally, everything works fine, but as soon as I'm hosting it in docker container, I cannot reach it with Postman.

Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:5.0-focal AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS build
WORKDIR /src
COPY ["HealthCheck/HealthCheck.csproj", "HealthCheck/"]
RUN dotnet restore "HealthCheck/HealthCheck.csproj"
COPY . .
WORKDIR "/src/HealthCheck"
RUN dotnet build "HealthCheck.csproj" -c Release -o /app/build

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

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

When I run docker container it starts normally:

=info: Microsoft.Hosting.Lifetime[0]

Now listening on: http://0.0.0.0:80

info: Microsoft.Hosting.Lifetime[0]

Application started. Press Ctrl+C to shut down.

info: Microsoft.Hosting.Lifetime[0]

Hosting environment: Production

info: Microsoft.Hosting.Lifetime[0]

Content root path: /app

(Port is mapped to 5020) I'm sending the request: http://localhost:5020/api/checktrue and I get Error: socker hang up

When I'm doing the same request on my machine it works fine.

Do you have any idea how to solve that?



Solution 1:[1]

I had the similar issue. Try to call your endpoint http://localhost:5020/api/checktrue with cURL.

The cURL tool gave me a more telling answer than the Postman did.

curl: (52) Empty reply from server

The error could be caused if cURL is asked to do plain HTTP on a server that does HTTPS.

Your .NET API in the container probably is listening on port 80 and also 443. Even if launchsettings.json says differently. This setting don't change the startup for the Docker container actually.

My sollution was to set default URL with Kestrel configuration in the Program.cs class.

In .NET5 it would be like

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseUrls("http://localhost:80");
            });

In .NET6 the UserUrls() method is not using anymore, it will look as follow.

var builder = WebApplication.CreateBuilder(args);

//...

builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(80);
});

//...

var app = builder.Build();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mikolaj