Docker部署ASP.NET Core Web API遇ERR_EMPTY_RESPONSE问题求助
解决Docker运行ASP.NET Core Web API时的ERR_EMPTY_RESPONSE问题
我用Docker运行ASP.NET Core Web API时碰到了ERR_EMPTY_RESPONSE错误,执行docker compose up后容器启动正常,但访问localhost:8080返回空白响应页面。我猜测可能和Kestrel有关,但还没找到解决办法。以下是我的配置和代码:
docker-compose.yml 文件
version: "3.9" services: microservices: image: "aspdotnetapp" container_name: api_app build: context: . ports: - "8080:3000" networks: - apiapp-network depends_on: - sql sql: image: "mcr.microsoft.com/mssql/server:2019-latest" container_name: sql_server2019 ports: - "1433:1433" environment: - ACCEPT_EULA=y - SA_PASSWORD=/1A2b3c4d networks: - apiapp-network networks: apiapp-network: driver: bridge
Dockerfile 文件
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base ENV PORT=3000 WORKDIR /app EXPOSE 3000 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["ShoppingMicroservices.csproj", "."] RUN dotnet restore "./ShoppingMicroservices.csproj" COPY . . WORKDIR "/src/." RUN dotnet build "ShoppingMicroservices.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "ShoppingMicroservices.csproj" -c Release -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "ShoppingMicroservices.dll"]
appsettings.json 文件
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "ServicesDbContextConnection": "Server=(localdb)\\MSSQLLocalDB;Database=ServicesDB;Trusted_Connection=True;MultipleActiveResultSets=True;TrustServerCertificate=True", "DockerDbContextConnection": "Server=sql_server2019;Database=ServicesDb;User Id=SA;Password=/1A2b3c4d;MultipleActiveResultSets=true;TrustServerCertificate=True" } }
Program.cs 代码
using Microsoft.EntityFrameworkCore; using ShoppingMicroservices.Controller; using ShoppingMicroservices.Controller.Api; using ShoppingMicroservices.Model; using System.Text.Json.Serialization; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("DockerDbContextConnection") ?? throw new InvalidOperationException("Connection string 'DockerDbContextConnection' not found."); builder.Services.AddScoped<IProductRepository, ProductRepository>(); builder.Services.AddScoped<ICategoryRepository, CategoryRepository>(); builder.Services.AddScoped<IExchangeRateRepository, ExchangeRateRepository>(); builder.Services.AddScoped<IOrderRepository, OrderRepository>(); builder.Services.AddScoped<InventoryController, InventoryController>(); builder.Services.AddScoped<NotificationController, NotificationController>(); builder.Services.AddControllers().AddJsonOptions(options => { options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; }); builder.Services.AddDbContext<ServicesDbContext>(options => { options.UseSqlServer(builder.Configuration["ConnectionStrings:DockerDbContextConnection"]); }); var app = builder.Build(); app.UseStaticFiles(); if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.MapDefaultControllerRoute(); using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; var context = services.GetRequiredService<ServicesDbContext>(); if (context.Database.GetPendingMigrations().Any()) { context.Database.Migrate(); } } DbInitializer.Seed(app); app.Run();
问题排查与解决方案
1. Kestrel端口绑定不生效
ASP.NET Core 6不会自动读取PORT环境变量绑定端口,需显式配置:
- 方案一:修改Program.cs指定端口
var builder = WebApplication.CreateBuilder(args); // 添加Kestrel端口配置 builder.WebHost.ConfigureKestrel(options => { var port = int.Parse(Environment.GetEnvironmentVariable("PORT") ?? "3000"); options.ListenAnyIP(port); // 监听容器内所有IP的3000端口 }); // 其余代码不变 - 方案二:修改Dockerfile的ENTRYPOINT
ENTRYPOINT ["dotnet", "ShoppingMicroservices.dll", "--urls", "http://0.0.0.0:3000"]
2. 数据库启动延迟导致应用阻塞
depends_on仅保证容器启动顺序,不保证SQL Server服务就绪,需添加健康检查:
- 在docker-compose.yml的
sql服务中添加健康检查:sql: # 原有配置不变 healthcheck: test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P /1A2b3c4d -Q 'SELECT 1' || exit 1"] interval: 10s timeout: 5s retries: 5 - 修改
microservices服务的depends_on:microservices: # 原有配置不变 depends_on: sql: condition: service_healthy
3. 路由配置不匹配
默认路由MapDefaultControllerRoute()适用于MVC项目,API项目建议使用属性路由:
- 替换
app.MapDefaultControllerRoute();为:app.MapControllers(); // 映射所有带[ApiController]属性的控制器 - 确保API控制器添加属性路由标记:
之后可通过[ApiController] [Route("api/[controller]")] public class ProductsController : ControllerBase { // 示例接口 [HttpGet] public IActionResult GetAll() { // 业务逻辑 } }localhost:8080/api/products访问接口。
4. 应用启动异常
查看容器日志确认应用是否真的启动成功:
docker logs api_app
如果存在数据库迁移失败、种子数据初始化错误等异常,需修复对应问题后重新构建镜像。
内容的提问来源于stack exchange,提问作者aspq
相关产品推荐
相关产品推荐

