My SQL Server databases are running fine as Docker containers and I am able to connect in SSMS, however when my web app attempts to connect to these SQL Server instances it fails. See exception error below:
EPiServer.Framework.Initialization.InitializationEngine[0]
Initialize action failed for 'Initialize on class EPiServer.Data.DataInitialization, EPiServer.Data, Version=12.4.2.0, Culture=neutral, PublicKeyToken=- - - -'
Microsoft.Data.SqlClient.SqlException (0x80131904): 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: Could not open a connection to SQL Server)
You can see my docker-compose
file below:
version: "3.9"
services:
sql-commerce:
container_name: "sql-commerce"
image: mcr.microsoft.com/azure-sql-edge
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Passw0rd123!
- DB_NAME=commerce
ports:
- '1433:1433'
volumes:
- ./databases_project/files/data/commerce:/var/opt/mssql/data
sql-cms:
container_name: "sql-cms"
image: mcr.microsoft.com/azure-sql-edge
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Passw0rd123!
- DB_NAME=cms
ports:
- '8080:1433'
volumes:
- ./databases_project/files/data/cms:/var/opt/mssql/data
web:
build: .
environment:
EcfSqlConnection: "sql-commerce"
EPiServerDB: "sql-cms"
ports:
- '3080:80'
This then speaks to a Dockerfile
in the same level:
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /ProjectName
COPY ["Applications/Website.Src/Website.Src.csproj", "Website.Src/"]
RUN dotnet restore "Website.Src/Website.Src.csproj" --source https://api.nuget.org/v3/index.json --source https://nuget.optimizely.com/feed/packages.svc/
COPY . .
WORKDIR "/ProjectName/Applications/Website.Src"
RUN dotnet build "Website.Src.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Website.Src.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Website.Src.dll"]
My connection string looks like the following:
"ConnectionStrings": {
"EcfSqlConnection": "Server=localhost,1433;Database=projectCommerce;User Id=sa;Password=Passw0rd123!;MultipleActiveResultSets=True",
"EPiServerDB": "Server=localhost,8080;Database=projectCms;User Id=sa;Password=Passw0rd123!;MultipleActiveResultSets=True"
},
Any thoughts on where I am going wrong here?
Update
I have attempted to target the sql container names rather than local host in my connection string, however even that fails to connect.
"ConnectionStrings": {
"EcfSqlConnection": "Server=sql-commerce,1433;Database=projectCommerce;User Id=sa;Password=Passw0rd123!;MultipleActiveResultSets=True",
"EPiServerDB": "Server=sql-cms,8080;Database=projectCms;User Id=sa;Password=Passw0rd123!;MultipleActiveResultSets=True"
},
3
Answers
In your docker-compose, each container acts as its own host. When you refer to
localhost
in your connection string, the web container sees this as itself, not the host (docker) machine.You can make things complicated in docker-compose by setting up different networks too, but by default, your containers will all be on the same network. I like to specify a host name for each container, like this:
Then, you can use that name in your connection string.
You might also look at the difference between
ports
andexpose
if you don’t want the sql services open to the host machine –expose
allows you to keep them inside the docker network only. Right now, I think you would need to specify port1433
for both connections (internal to the docker network) where the second one is only listening on8080
on the host machine.You cannot communicate between containers using localhost. Using localhost inside a container will only point to itself.
Docker has a DNS server built in and containers can connect between each other using the container name like you did, but your database names is still wrong in your example, according to your compose file they should be commerce and cms.
I had the same error, try removing the port from the connection string as follows: