Reputation: 933
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
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
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