Docker部署的API无法连接Docker中的SQL Server问题排查
问题描述
尝试在Docker中运行.NET API并部署SQL Server,但API无法连接到SQL Server,报错:
未处理的异常。Microsoft.Data.SqlClient.SqlException (0x80131904): 建立与SQL Server的连接时发生了与网络相关或特定于实例的错误。找不到服务器或无法访问。验证实例名称是否正确,以及SQL Server是否配置为允许远程连接。(provider: TCP Provider, error: 40 - 无法打开到SQL Server的连接: 无法打开到SQL Server的连接)
相关配置文件如下:
docker-compose.yml
version: '3.7' services: musicapi: build: context: . ports: - 80:80 environment: Authentication:Enabled: 'true' restart: always depends_on: - testdb testdb: image: mcr.microsoft.com/mssql/server:2017-latest ports: - "1433:1433" environment: TZ: Europe/Amsterdam ACCEPT_EULA: "y" SA_PASSWORD: Password01 volumes: - mssql_data:/var/opt/mssql/data restart: always volumes: mssql_data:
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:6.0 as build WORKDIR /src COPY . . RUN dotnet restore RUN dotnet build -c Release RUN dotnet publish -c Release -o ./out FROM base AS final WORKDIR /app COPY --from=build /src/out . # The following 2 lines are required for solving: # "Globalization Invariant Mode is not supported" error. RUN apk add --no-cache icu-libs ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false ENTRYPOINT ["dotnet", "Test.Api.dll"]
连接字符串
"ConnectionStrings": { "DefaultConnection": "Server=localhost,1433;Database=test.db;User ID=sa;Password=Password01;TrustServerCertificate=True;" }
解决方案
1. 修改连接字符串的服务器地址
在Docker Compose的默认网络中,容器之间通过服务名称互相访问,而非localhost。当前SQL Server的服务名称是testdb,因此连接字符串需修改为:
"ConnectionStrings": { "DefaultConnection": "Server=testdb,1433;Database=test.db;User ID=sa;Password=Password01;TrustServerCertificate=True;" }
2. 解决容器启动顺序的局限性
depends_on仅保证testdb容器先启动,但不会等待SQL Server服务完全就绪。API启动时数据库可能还在初始化,导致连接失败。可通过以下方式优化:
- 在API启动逻辑中添加连接重试机制(比如用Polly库实现)
- 为SQL Server容器添加健康检查,确保服务就绪后再启动API:
修改testdb服务配置:
同时修改testdb: # 原有配置不变 healthcheck: test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Password01 -Q 'SELECT 1' || exit 1"] interval: 10s timeout: 3s retries: 10musicapi的依赖条件:musicapi: # 原有配置不变 depends_on: testdb: condition: service_healthy
3. 确认目标数据库存在
连接字符串中的test.db不会被SQL Server自动创建。如果API没有内置数据库初始化逻辑(比如EF Core迁移),需手动创建:
- 进入SQL Server容器:
docker exec -it <容器ID> /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Password01 - 执行创建命令:
CREATE DATABASE [test.db];
内容的提问来源于stack exchange,提问作者Mernayi
相关产品推荐
相关产品推荐

