EF context not responding in docker

.net c# core docker entity-framework-core

Question

I just upgraded my Web API application to .NET core 3.0, all works fine when running in debug mode in IIS Express, but context does not respond when running in docker container either on server or in VS debug. No error thrown, just never responds.

I tried deploying an updated image to server which is where I first noticed the issue. I then tried running as docker in vs to debug. I have updated all NuGet packages and set frameworks to .NET Core 3.0 or .NET Standard 2.1. I have inspected the context connection string in debug and it appears to be correct. I rolled back to an earlier image using .NET core 2.2 and all worked as expected using the same startup parameters. I created a test method that does not use context and it returns correct values on server and in VS docker debug. I tried changing the method to use synchronous call to context, but no change in behavior. The test database is very small, only 3 records in the table being queried.

    public async Task<List<SendingSystemInfoResponse>> getSendingSystemInfoList()
    {
        try
        {
            return await _context.EmailSendingSystem.Where(m => !m.Deleted && m.Active == true).Select(m => new SendingSystemInfoResponse
            {
                SystemId = m.EmailSendingSystemId,
                SystemName = m.Title,
                SystemDescription = m.Description

            }).ToListAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, string.Format("EmailDataAccess: Exception retrieving EmailSendingSystem List"));
            throw;
        }
    }

If there were an error connecting to the SQL Server, or if the SQL request timed out, I would expect to hit the catch block code, but this never happens.

Here is the content of the docker file, I'm not sure if my targets for base and build images are correct. They seem to work, but might be the cause of my issue.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["EmailAutomation.API/EmailAutomation.API.csproj", "EmailAutomation.API/"]
COPY ["EmailAutomation.API/NuGet.Config", "/src"]
RUN dotnet restore "EmailAutomation.API/EmailAutomation.API.csproj"
COPY . .
WORKDIR "/src/EmailAutomation.API"
RUN dotnet build "EmailAutomation.API.csproj" -c Release -o /app

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

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

------Update----- So, I've been working on this off and on today, and have a little more info that might help someone point me in the right direction. I created a simple test Web API project with an EF connection to SQL Server running on my local PC using .NET core 3.0 and the latest NuGet packages, and enabled TCP/IP connections to SQL Server running locally. I was able to get it to connect to the database and return values.

Next, I created a copy of the test database on my local SQL Server. This also worked, the Web API in the original question running in Docker connected and returned data. I then changed the connection string to point back to the test SQL Server and the process hangs in the same spot with no error. Next, I tested it with the connection still pointed to the test SQL Server but running in IIS Express rather than Docker. Again, everything worked as expected.

I then tried running the previous release docker image which uses .NET Core 2.2, and it also returned data from the test SQL Server.

What could be the reason that I can not connect via IP to the test SQL Server using .NET Core 3.0 in Docker when all other combinations work just fine.

------Update 2----- I created the necessary database for my new simple test Web API project on the Test SQL Server, and changed the simple Web API project connection string. This new, clean, simple, .NET Core 3 project also did not connect to the Test SQL Server when running as Docker, but worked fine when running on IIS Express. It also worked fine when running in Docker but connecting to my local DB by IP.

Something has changed with .NET Core 3 in Docker that is stopping it from connecting to the external database server. Anybody have any ideas on what I need to do to resolve this?

--UPDATE 3 ----- Thanks to MATT! After reading Matt's response, I wasn't able to get the RUN commands to work within the docker file, but changing my base image to bionic did work. I have also been working with Microsoft support who also pointed me to the link that Matt provided. Maybe I just didn't place the RUN commands in the right location, so if anyone can provide a sample docker file using the RUN commands to resolve this issue, I would be grateful. Here is an updated docker file from a simple test project:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-bionic AS base
    WORKDIR /app
    EXPOSE 80

    FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
    WORKDIR /src
    COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
    RUN dotnet restore "WebApplication1/WebApplication1.csproj"
    COPY . .
    WORKDIR "/src/WebApplication1"
    RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build

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

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

---Final Update -----

I tried the RUN commands in the docker file again, but got it right this time. Here is that version of the docker file.

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
    WORKDIR /app
    RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
    RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
    EXPOSE 80

    FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
    WORKDIR /src
    COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"]
    RUN dotnet restore "WebApplication1/WebApplication1.csproj"
    COPY . .
    WORKDIR "/src/WebApplication1"
    RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build

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

    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "WebApplication1.dll"]
1
3
11/4/2019 8:22:47 PM

Accepted Answer

I believe the issue you're running into is documented here: https://github.com/dotnet/SqlClient/issues/222. As you said, something did change with .NET Core 3 because those Docker images are based on Debian Buster by default. Buster is configured to use 1.2 as the minimum TLS protocol, a change from the previous version (see https://www.debian.org/releases/stable/amd64/release-notes/ch-information.en.html#openssl-defaults).

This can be temporarily fixed by adding the following to the Dockerfile:

RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf

This is not a great solution because it is essentially downgrading the version of TLS. The better long-term solution is to enable TLS 1.2 on the SQL Server (see https://support.microsoft.com/en-us/help/3135244/tls-1-2-support-for-microsoft-sql-server).

2
10/23/2019 9:06:49 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow