23

I have pulled and run SQL Server 2017 container image using the following command:

docker pull microsoft/mssql-server-linux
docker run --name mssql -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=!Abcd123' -p 1433:1433 -d microsoft/mssql-server-linux

And I also deployed an ASP.NET Core Web API application to a Docker container, using the following commands:

dotnet publish -c Release -o Output
docker build -t apitest .
docker run -p 3000:80 --name apitest_1 apitest

The content of Dockerfile:

FROM microsoft/dotnet
COPY Output /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "DockerSQLTest.dll"]

In my Web API application, I have created an Entity Framework Core migration which will create the database and seed some data. In Configure method of Startup class, I add the following code to apply the pending migrations to the database:

public async void Configure(IApplicationBuilder app,
                            IHostingEnvironment env, 
                            StudentDbContext dbContext)
{
    await dbContext.Database.MigrateAsync();
    ...
}

And the database connection string is retrieved from appsettings.json which contains the following section:

"ConnectionStrings": {
    "DefaultConnection": "Server=localhost,1433;Database=student;User Id=sa;Password=!Abcd123;"
}

But the app cannot run correctly, the exception message:

fail: WebApplication6.Startup[0]
  System.Threading.Tasks.TaskCanceledException: A task was canceled.
     at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
     at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
     at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass20_0.<<ExistsAsync>b__0>d.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
     at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.ExistsAsync(CancellationToken cancellationToken)
     at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)

Is there anything wrong?

1
  • 1
    Add -h mssql to your docker run command. That will allow you to connect to the SQL container by that name (Server=mssql). Commented Oct 22, 2018 at 10:48

5 Answers 5

23

Docker has a DNS server built in, and containers connect to each other by the container name. In your case you named the SQL Server container mssql so that's the server name you need to put into your connection string for the .NET app: Server=mssql;Database=student;User Id=sa;Password=!Abcd123;.

Check out the .NET Core album viewer sample on GitHub, which uses Docker Compose to define a multi-container app.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked perfectly with the default docker setup in visual studio. Via container orchestrator support.
19

I resolved the issue by inspecting container network firstly then find the network IP and put to appsetting.json

 "ConnectionStrings": {
    "DefaultConnection": "Server=172.17.0.2;Database=VehicleKey;User Id=sa;Password=p@ssW0rd;"
  }

inspect docker network

find name of SQLSERVER enter image description here

2 Comments

Will this not be a manual operation all the time to find the IP and connecting to it..? I would prefer the answer above by Elton to use the container name.
The other answer looks cleaner but the name of the container will not resolve to the dns entry in the bridge. Probably something that I have in my config.
2

First of all, when you are using two or more containers, there couldn't be any localhost connections. Each docker container has own internal network IP. Once you started a container with an exposed port to be able to connect to that container you need to specify host IP (where container actually running).

So, as example, you should have next string for connection:

Server=192.168.1.99,1433;Database=student;User Id=sa;Password=!Abcd123;

where: 192.168.1.99 - actual IP of the host where docker container running.

Comments

0

You must know Docker container Ip address. You can get it executing ipconfig in cmd

Windows ipconfig

Use this IP for connection to SQL Server

Connect to Sql Server

If you are using Linux or Linux installed on WSL execute ifconfig from bash console

Linux ifconfig

Connecto to SQL

In the case when Linux is installed in your local WSL both IP addresses routes to the same SQL Server instance

Two Ip addresses to the same SQL Server Instance

Comments

0

Connection to SQL Server running in a container behaves differently. If using SSMS to connect it, 127.0.0.1,1433 would work but using it to connect from another container app will not. Another option is to use the host machine's IP but if you frequently change the network while working (Ex. office/home), you will end up changing the IP every time making it frustrating.

On Windows, use

host.docker.internal

docker creates a custom domain in the host file to reach containers.

The sample connection string would be like this:

Server=host.docker.internal,1433;Database=YourDatabase;User Id=sa;Password=!Abcd123;

This works even when you move to different networking.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.