Docker .NET Web API Dev Certs "Error: The SSL connection could not be established, see inner exception." on Some Endpoints

Viewed 91

Update: It appears to be some sort of certificate error since I added the following to my API controllers and calls are able to be made:

[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
    private HttpClientHandler handler = new HttpClientHandler();

    private static HttpClient _httpClient;


    public MyController()
    {
        handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
        _httpClient = new HttpClient(handler);
    }
...
}

However, I am still unsure what the issue is since I should be able to perform API calls with the self-signed cert. How do I remove the need to have HttpClientHandler.DangerousAcceptAnyServerCertificateValidator?

Original

I am developing a .NET 6 web API Docker container targeting Linux while my host environment is Windows. I can access all endpoints when running locally using dotnet run and building the production build with dotnet publish -c Release -o out and dotnet out/my-app.dll.

However, when I run the app inside a docker container, only one endpoint is accessible while the others have a 404 Not Found error: Error: The SSL connection could not be established, see inner exception. Firstly, where is the inner exception. I cannot seem to find it in the Chrome dev tools or in my API tool (Insomnia.rest). Secondly, I believe I have configured the dev cert correctly.

These are my steps:

  1. Run dotnet dev-certs https --clean and check certmgr.exe if the cert was actually deleted and delete if needed.
  2. Create a new cert with dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p {password here}.
  3. Trust the cert with dotnet dev-certs https --trust

Here is my Dockerfile:

Note: I'm using a private container repo but the image is the stock one that can be found on Dockerhub.

FROM myprivaterepo/dotnet/sdk:6.0.202-bullseye-slim-amd64 AS build

WORKDIR /app

COPY *.csproj .
RUN dotnet restore

COPY . .
RUN dotnet publish -c Release -o out

FROM myprivaterepo/dotnet/aspnet:6.0.4-bullseye-slim-amd64

WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 5000
EXPOSE 5001

ENV ASPNETCORE_URLS=https://+:5001;http://+:5000

COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "mantis-server.dll"]

Next I build the container: docker build -t my-app .

Then, I run the app: docker run --rm -it -p 5001:5001 -e ASPNETCORE_HTTPS_PORT=5001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="password here" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -e ASPNETCORE_ENVIRONMENT=Development -v ~/.aspnet/https:/https:ro -v ~/devsecrets:/.microsoft/usersecrets my-app

There are three endpoints: /api/weatherforecast, /api/users?userId=1, and /api/cart?userId=1&cartId=1. I am able to access /api/weatherforecast without issue, but the other two endpoints result in the Error: The SSL connection could not be established, see inner exception.

I'm not sure what the issue may be. Each of these endpoints is handled by a separate controller. There is a note in Insomnia that reads: * Re-using existing connection! (#10) with host localhost but I'm not sure what that means.

If you need any more information, please let me know. Thanks!

1 Answers

I had same issue and I fixed it by the way in the bottom :
First this is my docker file :

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app


FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Shoppify.Market.App.Api/Shoppify.Market.App.Api.csproj", "Shoppify.Market.App.Api/"]
COPY ["Shoppify.Market.App.Infrastructure/Shoppify.Market.App.Infrastructure.csproj", "Shoppify.Market.App.Infrastructure/"]
COPY ["Shoppify.Market.App.Identity/Shoppify.Market.App.Identity.csproj", "Shoppify.Market.App.Identity/"]
COPY ["Shoppify.Market.App.Service/Shoppify.Market.App.Service.csproj", "Shoppify.Market.App.Service/"]
COPY ["Shoppify.Market.App.Persistence/Shoppify.Market.App.Persistence.csproj", "Shoppify.Market.App.Persistence/"]
COPY ["Shoppify.Market.App.Domain/Shoppify.Market.App.Domain.csproj", "Shoppify.Market.App.Domain/"]
RUN dotnet restore "Shoppify.Market.App.Api/Shoppify.Market.App.Api.csproj"
COPY . .
WORKDIR "/src/Shoppify.Market.App.Api"
RUN dotnet build "Shoppify.Market.App.Api.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Shoppify.Market.App.Api.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

EXPOSE 5107
EXPOSE 7107

ENTRYPOINT ["dotnet", "Shoppify.Market.App.Api.dll"]

Actually when you want to redirect your application to ssl port, you have to generate its certificate, therefore do it in the docker-compose.yml file like me :

version: '3.9'
services:
    myapi:
      build:
        context: .
        dockerfile: ./Dockerfile
      ports:
        - "5107:5107"
        - "7107:7107"
      volumes:
        - ./Shoppify.Market.App.Api/appsettings.Development.json:/app/appsettings.json
        - ./Shoppify.Market.App.Api/values.json:/app/values.json
        - ~/.aspnet/https:/https:ro
      depends_on:
        - sqlserver
      environment:
        - ASPNETCORE_URLS=http://+:5107
        - ASPNETCORE_HTTPS_PORT=https://+:7107
        - ASPNETCORE_ENVIRONMENT=Development
        #----------------------------------------------------------------------------
        - ASPNETCORE_Kestrel__Certificates__Default__Password=12345678
        - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
        # dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p { password here } AND THEN dotnet dev-certs https --trust
        #-------------------------------------------------------------------------
    sqlserver:
      image: mcr.microsoft.com/mssql/server:2019-latest
      environment:
            SA_PASSWORD: "@Li12345678"
            ACCEPT_EULA: "Y"

After "environment" section and that last two lines ( I mean -> ASPNETCORE_Kestrel__Certificates__Default__Password & ASPNETCORE_Kestrel__Certificates__Default__Path) will generate certificate. My application ran by this instructions. Don't forget that run this in the cmd (dotnet dev-certs https -ep %USERPROFILE%.aspnet\https\aspnetapp.pfx -p { password here } AND THEN dotnet dev-certs https --trust).
I Hope I could fix your problem.

Related