sql-serverdockernetwork-programmingdnswindows-container

Can't connect to local SQL Server using windows container, but can using Linux container


I'm trying to just have a basic connection with a SQL Server (not in a container) that is running on my local dev machine (Windows 11) and connect to it using a windows container.

I keep getting an error similar to this:

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: 0 - The wait operation timed out.)

And here is the Dockerfile (for one of the applications that isn't working). This was generated by Visual Studio:

FROM mcr.microsoft.com/dotnet/runtime:7.0 AS base
WORKDIR /app

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

FROM build AS publish
RUN dotnet publish "EmailTestDocker.csproj" -c Release -o /app/publish /p:UseAppHost=false

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

I've tried initially connecting with a C# .NET Core console app. If I run this without the Docker container using this connection string it does work and I get data

Connection String: "Server=tcp:(computer name or localhost),1433;Initial Catalog=(db name);Persist Security Info=False;User ID=(user);Password= password);MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=False;"

I can also run that in a linux container and get data, except I need to use either the computer name or host.docker.internal for the server name. If I run it in a windows container nothing works.

I've also tried using a python app with the same results.

My guess is that the windows container can't connect to the SQL Server 1433 port due to some firewall or network issue.

I've also reproduced this issue on another windows laptop, so it's not just this dev machine.

When I do an interactive PowerShell console with the container and run some different commands here are the results:

Resolve-DnsName host.docker.internal

Resolve-DnsName : host.docker.internal : DNS name does not exist ... (more to this error)


Resolve-DnsName (computer name)

(computer name).local    AAAA   60    Answer     fe80::dc77:c5a9:10f9:b3a
(computer name).local                            A      60    Answer     172.25.80.1


Test-NetConnection -ComputerName (computer name) -Port 1433
 

WARNING: TCP connect to (fe80::dc77:c5a9:10f9:b3a%4 : 1433) failed
WARNING: TCP connect to (172.25.80.1 : 1433) failed
ComputerName : (computer name)
RemoteAddress : fe80::dc77:c5a9:10f9:b3a%4
RemotePort : 1433
InterfaceAlias : Ethernet
SourceAddress : fe80::a94f:9732:c448:9692%4
PingSucceeded : True
PingReplyDetails (RTT) : 0 ms
TcpTestSucceeded : False

docker network inspect nat (silly_poincare is the container name)

[
    {
        "Name": "nat",
        "Id": "c1eb0498ed676f5b3bebf3a3359cc769599f2395b20ffdf19b73f6bbb55cb8d5",
        "Created": "2023-08-27T13:58:49.6748484-05:00",
        "Scope": "local",
        "Driver": "nat",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "windows",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.25.80.0/20",
                    "Gateway": "172.25.80.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "c0b7c2914187f819659142a2daf3987ec9c1c91abb82e949870d0441ccc77c1f": {
                "Name": "silly_poincare",
                "EndpointID": "84651f3c036d038e96047a8836fdf4f486dbec945d0c1ccff2f5cc4aa55edd42",
                "MacAddress": "00:15:5d:5c:d4:c0",
                "IPv4Address": "172.25.94.69/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.windowsshim.hnsid": "(guid)",
            "com.docker.network.windowsshim.networkname": "nat"
        },
        "Labels": {}
    }
]

Also it does look like I'm using hyper V although I don't think I'm using Hyper-V containers

*Update 8/29/2023 I'm now wondering if this is a sql server issue. I tried using SSMS to connect to the sql server on my dev machine from another machine on my local network. I can ping the dev machine, but can't connect via SSMS (same error as above).

I ran SQLCHECK. There is a lot of data, but I am seeing a few things that might help:

The following HOSTS file entries were found for this machine:

192.168.0.129 host.docker.internal
192.168.0.129 gateway.docker.internal
127.0.0.1 kubernetes.docker.internal

The following IP addresses are associated with this machine:

Address Family  Address                     
--------------  ----------------------------
InterNetworkV6  fe80::f5b1:d691:6bd8:2d8a%12
InterNetworkV6  fe80::64c2:f44e:925:574c%57 
InterNetworkV6  fe80::ed65:3592:dec4:350b%39
InterNetworkV6  fe80::3bba:af49:b8e:87d7%29 
InterNetworkV6  fe80::dc77:c5a9:10f9:b3a%20 
InterNetwork    192.168.0.129               
InterNetwork    172.8.128.1                 
InterNetwork    172.25.0.1                  
InterNetwork    172.24.112.1                
InterNetwork    172.25.80.1

No SQL Aliases were found on this machine.


Solution

  • Turns out it was the windows firewall. I had the bright idea to just turn it off to see if that was it and bing the windows container could connect to my local sql server using either the hostname or the host.docker.internal. I looked up how to add the firewall exception

    New-NetFirewallRule -DisplayName "SQLServer default instance" -Direction Inbound -LocalPort 1433 -Protocol TCP -Action Allow
    New-NetFirewallRule -DisplayName "SQLServer Browser service" -Direction Inbound -LocalPort 1434 -Protocol UDP -Action Allow
    

    And then I turned the firewall back on and it still works. I got rid of MyPublic network from above and it still works with the default "nat" network that windows containers use by default (at least this version). Sorry if this was obvious to other people and I should have checked the firewall to begin with, but none of the tutorials mention this. *It is important to note that you probably want to exclude Public networks, but I don't know much about firewalls.

    Thanks to everyone who responded!