Marlon Brando aka Ben
Marlon Brando aka Ben

Reputation: 933

How to communicate between two docker containers (mssql and .net core app) got Connection refused 127.0.0.1:1433

I have a .net core 2.0 project which uses mssql server. I have Created a docker image and container for my .net core 2.0 and running on 9090:9090. I created it like below.

docker container run --name mytestapp --publish 9090:9090 --detach my_.netapp_image_name

and below is my connection string in .net core 2.0 app.

"DefaultConnection": "Server=127.0.0.1;Database=mydatabase;UserId=SA;Password=mydbpassword"

before this, I created a container for mssql server with below,

docker container run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<YourStrong!Passw0rd>' \
   -p 1433:1433 --name sql1 \
   -d microsoft/mssql-server-linux:2017-latest

Unhandled Exception: 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: TCP Provider, error: 35 - An internal exception was caught) ---> System.AggregateException: One or more errors occurred. (Connection refused 127.0.0.1:1433) ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: Connection refused 127.0.0.1:1433

NOTE: this works fine when I run my .net app via IDE(visual studio) and use db as docker mssql container. I ran these two containers separately. then I tried to run using docker-compose, but didn't work.

What am I doing wrong here. hope your help with this.

Upvotes: 5

Views: 5017

Answers (2)

BMitch
BMitch

Reputation: 263549

Containers each have their own network namespace by default. Compose will place all containers on a shared network and set an alias in DNS for the service name. So to connect between containers, all you need to do is point to your service name instead of the 127.0.0.1 (assuming mysql is your service name):

"DefaultConnection": "Server=mysql;Database=mydatabase;UserId=SA;Password=mydbpassword"

This is more portable and handles containers scaling/updating better than to attaching containers to the same network namespace.

Upvotes: 3

Rafal
Rafal

Reputation: 12619

So the issue here is the docker sandboxing. For each container that you run you can think of as different virtual environment that has its own host name, IP address and network. While using -p only forwards port form that internal network to host. So while you are running from VS you can point to your db using localhost (127.0.0.1:1433) just because you have exposed that port to host and your application is starting on host directly. When it is runing inside its own container localhost no longer refers to host but rather to that docker environment. To fix this you can run both containers in the same network (--network argument on run) and refer from one to another by host name (--name argument on run).

docker container run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<YourStrong!Passw0rd>' \
-p 1433:1433 --name sql1 \
-d microsoft/mssql-server-linux:2017-latest \
--name sql_server

docker container run \
--name mytestapp 
--publish 9090:9090 
--detach my_.netapp_image_name 
--network container:sql_server

and in your settings refer to your database as sql_server. To make this process less painful you can research docker-compose.

Upvotes: 2

Related Questions