Search code examples
sql-serverdocker

Connecting to a SQL Server database running in a Docker container from another docker container


I am creating a database in a Docker container via the following

docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=YourStrong@Passw0rd" -p 1433:1433 --network MyAppNetwork --name MyAppDb -d mcr.microsoft.com/mssql/server:2017-latest-ubuntu

I am then running my ASP.NET Core 3.0 application

docker run -p 5000:80 -e "ASPNETCORE_ENVIRONMENT=Development" --network MyAppNetwork --name MyApp myimage

Inside the app there is a connection string

Data Source=MyAppDb;Initial Catalog=MyAppDb;User ID=sa;Password=YourStrong@Passw0rd

and I perpetually get the 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: 40 - Could not open a connection to SQL Server)

I have tried MyAppDb,1433 localhost localhost,1433... nothing works

Docker documentation says you should be able to refer to other docker containers via their name as long as they are on the same network, but its not behaving as expected for me. I did try not specifying a network so the containers are just defaulting to the bridge, but nothing changed.

Note: I can connect to the database perfectly fine from my host machine, but from within the other docker container, nothing works.

Any ideas?

-- update --

docker network inspect MyAppNetwork

[
    {
        "Name": "MyAppNetwork",
        "Id": "2f334b2df38c199ef423fdbe65c15e33b43d983e91a3398d75f0d988d5588c13",
        "Created": "2019-10-03T10:40:40.3165785Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
"f3106bc710fe760e257dd05aace7e76827d953600e5520556b040706f10246fb": {
                "Name": "MyAppDb",
                "EndpointID": "c4c58df89b4117674a0db57dfe276086eb48dda36fcc6a0989425b65fc130c41",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
]

Solution

  • I spent many hours on this trying to do it "properly" but eventually I just gave up and went back to using the deprecated Links feature based solution within a docker-compose file

    https://docs.docker.com/network/links/

    Worked immediately without any issues what so ever. I will revisit this when the next major update to Docker comes out and removes the Link feature.

    docker-compose.yml

    version: "3.5"
    
    networks:
      myappnetwork:
        name: myappnetwork
    
    services:
      myapp:
        build: .
        restart: always
        container_name: myapp
        depends_on: [myappdb]
        environment:
          ASPNETCORE_ENVIRONMENT: Development
        networks:
          - myappnetwork
        ports:
          - 5000:80
        links:
          - myappdb
      myappdb:
        image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
        restart: always
        container_name: myappdb
        environment:
          ACCEPT_EULA: Y
          SA_PASSWORD: YourStrong@Passw0rd
        networks:
          - myappnetwork
        ports:
          - 1433:1433
    

    dockerfile

    FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build
    WORKDIR /app
    
    # copy csproj and restore as distinct layers
    COPY *.sln .
    COPY MyApp/*.csproj ./MyApp/
    RUN dotnet restore
    
    # copy everything else and build app
    COPY MyApp/. ./MyApp/
    WORKDIR /app/MyApp
    RUN dotnet publish -c Release -o out
    
    FROM mcr.microsoft.com/dotnet/core/aspnet:3.0 AS runtime
    WORKDIR /app
    COPY --from=build /app/MyApp/out ./
    ENTRYPOINT ["dotnet", "MyApp.dll"]
    

    appsettings.json

    {
      "ConnectionStrings": {
        "DefaultConnection": "Data Source=myappdb,1433;Initial Catalog=myappdb;User ID=sa;Password=YourStrong@Passw0rd"
      }
    }