3

I have a Windows docker container and a simple test app that is attempting to connect with the SQL Server running on the host, but it is unable to connect.

I am able to ping the host from the container using "ping -4 hostmachinename", but the SqlConnection Open method fails.

To test I run these commands:

docker build --tag=heydocker . docker run heydocker:latest

# Dockerfile:
FROM microsoft/dotnet-framework
WORKDIR /app
COPY . /app
EXPOSE 1433
CMD ["program.exe"]

This is my app code:

// program.cs:
using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;

namespace Test
{
    public static class program
    {
       const string CONNECT = "Data Source=docker.for.win.localhost;Database=MG108RC3_All;User ID=sa;Pwd=password;Network Library=dbmssocn";

        public static void Main()
        {
            Console.WriteLine( "Hello Docker" );

            try
            {
                using ( var con = new SqlConnection( CONNECT ) )
                {
                    con.Open();
                    Console.WriteLine( "Open SUCCESS" );
                }
            }
            catch ( Exception ex )
            {
                Console.WriteLine( $"ERROR: {ex.Message}" );
            }
        }
    }
}

I have tried omitting the EXPOSE in the Dockerfile, as well as using EXPOSE 1433:1433.

I have also tried using the actual machine name in the connection string, as well as host.docker.internal.

When using docker.for.win.localhost I get the exception: ERROR: 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 - No such host is known.)

When using the machine name I get: ERROR: 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.)

I have tried various options for --net, but since I am able to ping my host with the default network settings I am not confident that is the problem.

Jon Curry
  • 71
  • 1
  • 6
  • I have verified that I can assess MS SQL server on my host machine from another machine on the network. I have verified that I can access my host's IIS by host name from my docker container. I've verified connectivity from other machines on the network, scoured Google for hours looking for a definitive answer. There is so much confusion between linux/windows, MSSQL vs MySQL. It is hard to imagine such a simple test has no simple answer. I would think people would be doing this all the time. Maybe I'm just too dense to know what to look for. Oy this is frustrating! – Jon Curry Feb 25 '19 at 22:20

3 Answers3

0

You need to have a network connection between host and your docker container.

Also your trying to expose port 1433 from your container, which is not running the SQL Server service. This won't work.

You also need to check if your SQL Server is configured to allow TCP/IP connections from the SQL Server Configuration Manager.

See if this post helps you with resolving your issue: How to access host port from docker container

and this article https://nickjanetakis.com/blog/docker-tip-35-connect-to-a-database-running-on-your-docker-host

jbud
  • 694
  • 5
  • 7
  • Thanks for your response @jbud. My SQL Server is configured to allow TCP/IP connections, and enable remote access. The first link is where I found the idea to use host.docker.internal, without success. I can't ping that from my container so it doesn't seem to exist (I'm on docker 18.09.1). The other link suggests using ip addresses...seems rather stone age to not be able to use domain names, but I will give it a try. Since I can ping -4 MyMachineName it seems like networking is there - I just can't reach SQL Server. – Jon Curry Jan 29 '19 at 21:32
  • I guess you might have already did this, but did you verify if your SQL Server instance is accessible from the network from another machine on the network? If not, it might be a firewall issue on your host. – jbud Jan 30 '19 at 22:28
0

OK, I'm an idiot. I assumed that since I could access my SQL server from another machine on the network, that should be sufficient. But my firewall is disabled for our corporate network, and the container is using a private network (with firewall enabled). Turning off the firewall for private networks allowed the connection to succeed.

Whew!

Jon Curry
  • 71
  • 1
  • 6
  • Also note that "docker.for.win.localhost" in the original example did not work, but my host machine name did. – Jon Curry Feb 26 '19 at 15:02
0

The same issue bugged me for days and finally was able to solve it by following the steps below.

In my case the SQL server was hosted on Azure managed instance and exposed a private endpoint. The docker was able to resolve the DNS name of the Azure managed instance to a private IP address (as expected ). But this resolved IP was considered by the docker network/bridge as a locally running application because upon inspecting docker's bridge (docker network inspect bridge)The subnet of the bridge was found to be a range of IP addresses where the resolved IP of the SQL server also falls. Hence, the docker assumed the SQL server to be hosted in the same local network and not outside (here enterprise network). In my case the Windows VM I was working was already on the private network of the enterprise.

Solution:

In the docker desktop -> settings -> Docker Engine json file, add a new key value pair "bip": "<local IP address range which is outside of the resolved sql server IP>". Restart the docker desktop and the issue should be solved.