Firstly there are a few similar questions but I have tried all the suggestions I can find and nothing seems to work. If you can find one I haven't mentioned, please comment and I'll try it out.
The synopsis is I'm trying to connect a .NET Core 3.1 web api in a Docker container to SQL Server 2019 on my host, but it fails with System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 0 - Success).
I have:
- Docker (desktop) version 20.10.7, build f0df350 using WSL2
- SQL Server Developer 2019 15.0.2080.9
- Windows 10 Home 21H1
I have tried:
A different docker image
According to here people have success with mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic instead of mcr.microsoft.com/dotnet/core/aspnet:3.1
port mapping
various forms to docker run, including -p 1433:1433, -p 0.0.0.0:1433:1433, -p localhost:1433:1433
Connection Strings
My connection string is currently
"Server=host.docker.internal;Database=xxx;MultipleActiveResultSets=true;UID=sa;PWD='xxx';Integrated Security=false;TrustServerCertificate=true"
I have also tried Server=host.docker.internal,1433, Server='tcp:host.docker.internal\\SQLSERVER2019,1433', Server='tcp:host.docker.internal,1433', Server='host.docker.internal,1433'...
SQL Server configuration
TCP is enabled and listening on all interfaces, however I can't see an IP address in the range 192.168.65.0/24 which is what Docker desktop is configured to use.
SSMS works locally, and the web api app connects if it's not in a Docker container.
TLS 1.2
Some comments say it's due to a TLS error with a newer version of SQL Server, however I've tried the workarounds:
TrustServerCertificate=true- changing the minimum protocol on the container:
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf
Dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-bionic AS base
WORKDIR /app
EXPOSE 80
ENV ASPNETCORE_URLS=http://+:80
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /
COPY . .
RUN dotnet build my.csproj -c Release -o /app/build
FROM build AS publish
RUN dotnet publish my.csproj -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf
ENTRYPOINT ["dotnet", "my.dll"]
Full Stack trace
Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 0 - Success)
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at Microsoft.Data.SqlClient.SqlConnection.OpenAsync(CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
ClientConnectionId:88dafbd1-163f-486b-a750-ec3dbf5c75ff
Thanks!
[edit]
When I connect to localhost using SSMS, I get a different SQL Server instance. So I tried to connect to the correct named instance from the connection string using Server=host.docker.internal\SQLSERVER2019; I get the error:
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 25 - Connection string is not valid)
If I try and use Server=host.docker.internal\\SQLSERVER2019; I get
Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 25 - Connection string is not valid)
Note: I'm setting the connection string as an environment variable to docker run: -e ConnectionStrings__MyConnectionString="..."

