1
votes

I’m just beginning to get into Docker and I like my progress so far. But I am stumped by the following problem. I am trying to run a SQL Server database in one container and have my .Net Framework 4.5 web service running in a second container. If the connection string in the web service container uses the IP address of the db container, the connection is made successfully. If I try to use the host name I've specified, the following exception is thrown:

System.Data.Entity.Core.EntityException: The underlying provider failed on Open.

System.Data.SqlClient.SqlException: 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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

System.ComponentModel.Win32Exception: The network path was not found

I am running Docker for Windows Engine 19.03.8 on Windows 10 Enterprise, and using Windows Containers. Here are the commands and docker files I've used. My testing app is a simple console application that uses Entity Framework 6 to call a stored procedure that returns data from a table.

docker network create --driver nat mynat

Docker File for DB Container

FROM microsoft/mssql-server-windows-developer

ENV sa_password "Password123"
ENV attach_dbs "[]"

COPY . /

WORKDIR /

RUN powershell sqlcmd -S localhost,1433 -i CreateEMLDatabase.sql


RUN powershell set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord 

CMD powershell ./start -sa_password Password123 -attach_dbs \"%attach_dbs%\" -Verbose -ACCEPT_EULA 'Y'

docker build --rm --no-cache --tag mailservicedb:latest .

docker run --net mynat --ip 172.30.157.42 -d --name maildbctr --hostname maildbctr mailservicedb:latest

Connection string for the tester console:

connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=maildbctr;initial catalog=EML;User Id=MyLogin;Password=MyPassword;MultipleActiveResultSets=True;App=EntityFramework""

Docker File for Tester Console

FROM mcr.microsoft.com/windows/servercore:1903

WORKDIR /tester

COPY . .

#FIX DNS issues currently in Windows Containers
RUN powershell set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord 

CMD ContainerDbTester.exe

docker build --rm --no-cache --tag dbtester:latest .

docker run -it --net mynat --ip 172.30.157.43 --name dbtestctr --hostname dbtestctr dbtester:latest cmd

Inside the Tester container, I can ping the db container name:

ping maildbctr

Pinging maildbctr [fe80::11c5:f48c:92c1:7a36%4] with 32 bytes of data:
Reply from fe80::11c5:f48c:92c1:7a36%4: time<1ms
Reply from fe80::11c5:f48c:92c1:7a36%4: time<1ms
Reply from fe80::11c5:f48c:92c1:7a36%4: time<1ms
Reply from fe80::11c5:f48c:92c1:7a36%4: time=1ms

Ping statistics for fe80::11c5:f48c:92c1:7a36%4:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 1ms, Average = 0ms

But when I run the console exe, I get the exception thrown above.

Any help figuring out what step I’m missing is very much appreciated.

2

2 Answers

1
votes

I had a similar issue. My setup was this:

  • Database container mapping port 1433 to host port 31433;
  • App A running on the host;
  • App B in another container;

App A was able to connect to the database normally using localhost,31433, while App B was unable to connect using localhost.

After some research I was able to make App B connect to the database using host.docker.internal instead of localhost.

0
votes

I've worked multiple times with a similar setup (database + web platform) and I used to go for a docker-compose approach, it usually is more simple (it creates a network for each compose by default) and allowed me to keep track of multiple different configurations over time. DC's docs even present us an example and how networking works:

version: "3"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

In this example, you could use "db" to reference the database IP inside your web application.