我有一个带有 API 网关的 .NET 7 解决方案:一个 API 是网关,另外两个 API 是 WebAPI1 和 WebAPI2。这三个 API 都是 docker 化的项目。
我有另一个容器 - SQL Server dockerized 数据库。
我的电脑操作系统是Windows 11。
尽管我付出了一切努力,我仍无法将我的 Web API 连接到我的数据库。
这是我得到的错误:
Microsoft.Data.SqlClient.SqlException:“建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供程序:SQL 网络接口,错误:44 - 无法为 Windows 集成身份验证编写服务主体名称 (SPN)。可能的原因是未正确指定连接 API 调用的服务器、域名系统 (DNS) 查找失败或内存不足)'
错误发生在我的WebAPI1项目中,在
Program.cs
中,其中调用了迁移方法:
var applicationConnectionString = builder.Configuration.GetConnectionString("ApplicationConnection");
builder.Services.AddDatabaseContext(applicationConnectionString!);
builder.Services.AddIdentityContext(applicationConnectionString!);
builder.Services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(applicationConnectionString));
builder.Services.AddDbContext<IdentityContext>(options => options.UseSqlServer(applicationConnectionString));
using (var serviceScope = app.Services.GetService<IServiceScopeFactory>()!.CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetRequiredService<DatabaseContext>();
dbContext.Database.Migrate(); // The error is happening here
var identityContext = serviceScope.ServiceProvider.GetRequiredService<IdentityContext>();
identityContext.Database.Migrate();
}
这些是其他代码片段:
连接字符串:
"ApplicationConnection": "Data Source=127.0.0.1,8001;Initial Catalog=MyDatabase;User Id=sa; Password=Passw0rd!;Trusted_Connection=true;TrustServerCertificate=True"
我也尝试过:
"ApplicationConnection": "Server=127.0.0.1,8001;Database=MyDatabase;User Id=sa; Password=Passw0rd!;Trusted_Connection=true;TrustServerCertificate=True"
数据库上下文:
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
EntityOne.Configure(modelBuilder);
EntityTwo.Configure(modelBuilder);
EntityThree.Configure(modelBuilder);
EntityFour.Configure(modelBuilder);
}
public DbSet<EntityOne> EntityOne { get; set; }
public DbSet<EntityTwo> EntityTwo { get; set; }
public DbSet<EntityThree> EntityThree { get; set; }
public DbSet<EntityFour> EntityFour { get; set; }
public async Task<int> SaveChangesAsync()
{
return await base.SaveChangesAsync();
}
}
WebApi1
Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["WebAPIs.WebApi1/WebAPIs.WebApi1.csproj", "WebApi1.Calendar/"]
COPY ["Core/Core.csproj", "Core/"]
COPY ["Infrastructure/Infrastructure.csproj", "Infrastructure/"]
COPY ["Infrastructure/Infrastructure.csproj", "Infrastructure/"]
RUN dotnet restore "./WebAPIs.WebApi1/WebAPIs.WebApi1.csproj"
COPY . .
WORKDIR "/src/WebAPIs.WebApi1"
RUN dotnet build "./WebAPIs.WebApi1.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./WebAPIs.WebApi1.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=true
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WebAPIs.WebApi1.dll"]
docker-compose.yml
:
version: '3.4'
services:
database:
container_name: database
image: mcr.microsoft.com/mssql/server:2022-preview-ubuntu-22.04
environment:
- ACCEPT_EULA=Y
- SA_DB_NAME= MyDatabase
- SA_USER=sa
- SA_PASSWORD=Passw0rd!
# volumes:
# - sqlserver_data:/var/opt/mssql
ports:
- 127.0.0.1:8001:1433
webapis.gateway:
container_name: webapis.gateway
image: ${DOCKER_REGISTRY-}gateway
build:
context: .
dockerfile: WebAPIs.Gateway/Dockerfile
ports:
- 127.0.0.1:5020:80
- 127.0.0.1:7055:443
depends_on:
- database
webapis.webapi1:
image: ${DOCKER_REGISTRY-}webapisapi1
build:
context: .
dockerfile: WebAPIs. WebApi1/Dockerfile
ports:
- 127.0.0.1:5234:80
- 127.0.0.1:7207:443
depends_on:
- database
webapis.webapi2:
container_name: webapis. webapi2
image: ${DOCKER_REGISTRY-} webapisapi2
build:
context: .
dockerfile: WebAPIs.WebApi2/Dockerfile
ports:
- 127.0.0.1:5013:80
- 127.0.0.1:7090:443
depends_on:
- database
docker-compose.override.yml
:
version: '3.4'
services:
webapis.gateway:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_HTTP_PORT=80
- ASPNETCORE_HTTPS_PORT=443
ports:
- 127.0.0.1:5020:80
- 127.0.0.1:7055:443
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
webapis.webapis1:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
ports:
- 127.0.0.1:5234:80
- 127.0.0.1:7207:443
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
webapis.webapis2:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
ports:
- 127.0.0.1:5013:80
- 127.0.0.1:7090:443
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
我检查了很多东西,包括:
所以现在我不知道该怎么办,如果有人有一些解释或想法,我很乐意阅读!
如果您在容器中运行应用程序
127.0.0.1
将意味着容器本身显然没有运行数据库。由于您的 docker compose 文件将所有容器放置在同一网络(默认网络)中,因此您可以使用服务名称进行服务发现/IP 地址解析。因此,请在连接字符串中尝试类似以下内容:
"ApplicationConnection": "Data Source=database,8001;...."
我还建议使用环境变量来传递
ApplicationConnection
用于 docker compose 案例:
environment:
- ConnectionStrings__ApplicationConnection=Data Source=database,8001;....
另请参阅: