容器中ASP.NET Core应用连接SQL Server失败的问题求助
问题描述
基于示例创建了带独立用户身份认证和Docker支持的ASP.NET Core Web App项目,通过PowerShell创建了SQL Server容器,本地用SQL Server Management Studio测试连接(包括本地SQL Server和容器内SQL Server)均成功。但将ASP.NET项目通过VS运行在Docker中时,注册新账户时两种连接字符串均抛出SQL连接异常:
SqlException: 建立与SQL Server的连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确,并且SQL Server已配置为允许远程连接。 (provider: TCP Provider, error: 40 - 无法打开到SQL Server的连接: 无法打开到SQL Server的连接)
创建SQL Server容器命令:
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Test1234" -p 1433:1433 --name webappdb1 -d mcr.microsoft.com/mssql/server:2022-latest
尝试过的连接字符串:
"Data Source=localhost;Initial Catalog=WebApp5;User ID=SA;Password=Test1234;Current Language=German;MultipleActiveResultSets=true"
"Data Source=localhost,1433;Initial Catalog=WebApp5;User ID=SA;Password=Test1234;Current Language=German;MultipleActiveResultSets=true"
容器运行状态:
7ac6ef664be0 webapplication5:dev "tail -f /dev/null" 39 minutes ago Up 38 minutes 0.0.0.0:49154->80/tcp, 0.0.0.0:49153->443/tcp WebApplication5 265175f4f125 mcr.microsoft.com/mssql/server:2022-latest "/opt/mssql/bin/perm…" 43 minutes ago Up 43 minutes 0.0.0.0:1433->1433/tcp webappdb1
核心原因
Docker容器内的localhost指向容器自身,而非宿主机或SQL Server容器。宿主机上SSMS能通过localhost连接是因为端口映射将宿主机1433端口转发到了SQL容器,但容器内的应用无法通过localhost访问到另一个容器。
解决方案
1. 使用SQL Server容器名称作为数据源
修改appsettings.json中的连接字符串,将Data Source替换为SQL Server容器的名称webappdb1:
"ConnectionStrings": { "DefaultConnection": "Data Source=webappdb1;Initial Catalog=WebApp5;User ID=SA;Password=Test1234;Current Language=German;MultipleActiveResultSets=true" }
Docker默认会为同一网络下的容器提供DNS解析,直接使用容器名即可建立连接。
2. 确保容器处于同一Docker网络(可选,若步骤1无效)
如果默认网络的DNS解析有问题,可创建自定义网络并将两个容器加入:
- 创建自定义网络:
docker network create webapp-network
- 停止并删除现有容器:
docker stop WebApplication5 webappdb1 docker rm WebApplication5 webappdb1
- 重新创建SQL Server容器并加入网络:
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Test1234" -p 1433:1433 --name webappdb1 --network webapp-network -d mcr.microsoft.com/mssql/server:2022-latest
- 在Visual Studio中重新运行ASP.NET应用,VS会自动将应用容器加入同一网络。
3. 验证数据库初始化
确保WebApp5数据库已存在:
- 若使用EF Core,可在本地执行迁移命令:
Add-Migration InitialCreate Update-Database
- 或在
Program.cs中添加自动迁移代码,确保容器启动时自动创建数据库:
var scope = app.Services.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); dbContext.Database.Migrate();
内容的提问来源于stack exchange,提问作者Xeddon

