Docker部署ASP.NET Core 8.0应用容器外部无法访问问题求助
问题概述
ASP.NET Core 8.0 Web应用(集成Swagger UI)部署到Docker后,无法从容器外部访问。未使用Docker时,可通过http://localhost:90/swagger/index.html正常访问。
本地运行情况
本地执行.exe启动应用时输出:
info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:90 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production info: Microsoft.Hosting.Lifetime[0] Content root path: C:\Users\Username\Documents\Git\WetterApi\WetterApi
已编译应用文件结构
- Microsoft.OpenApi.dll
- Swashbuckle.AspNetCore.Swagger.dll
- Swashbuckle.AspNetCore.SwaggerGen.dll
- Swashbuckle.AspNetCore.SwaggerUI.dll
- WetterApi.deps.json
- WetterApi.dll
- WetterApi.exe
- WetterApi.pdb
- WetterApi.runtimeconfig.json
- appsettings.Development.json
- appsettings.json
- dockerfile
尝试过的Docker配置与操作
第一次配置
Dockerfile内容:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime COPY . . EXPOSE 90 ENV ASPNETCORE_ENVIRONMENT=Development ENV DOTNET_RUNNING_IN_CONTAINER=true ENTRYPOINT ["dotnet","/WetterApi.dll", "--server.urls","http://+:90"]
构建镜像命令:
docker build -t wetter_api_test .
启动容器命令:
docker run --rm -it -p 80:90 wetter_api_test
期望通过http://localhost:80/swagger/index.html访问。
容器启动输出:
warn: Microsoft.AspNetCore.Server.Kestrel[0] Overriding address(es) 'http://*:8080'. Binding to endpoints defined via IConfiguration and/or UseKestrel() instead. info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:90 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: /
执行curl测试报错:
curl http://localhost:80/swagger/index.html curl : The underlying connection was closed: The connection was closed unexpectedly.
第二次尝试:添加环境变量
在Dockerfile中添加以下环境变量,但问题未解决:
ENV DOTNET_URLS=http://+:90 ENV ASPNETCORE_URLS=http://+:90 ENV ASPNETCORE_HTTP_PORTS=90
第三次尝试:移除端口配置
修改后的Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime COPY . . ENV ASPNETCORE_ENVIRONMENT=Development ENV DOTNET_RUNNING_IN_CONTAINER=true ENTRYPOINT ["dotnet","/WetterApi.dll"]
启动容器命令:
docker run --rm -it -p 80:8080 wetter_api_test
测试仍报错:
curl http://localhost:80/swagger/index.html curl : The underlying connection was closed: The connection was closed unexpectedly.
docker ps显示端口映射正常:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2d179c430f50 wetter_api_test "dotnet /WetterApi.d…" About a minute ago Up About a minute 0.0.0.0:80->8080/tcp gracious_satoshi
解决方案
核心问题
容器启动日志显示应用仍在监听http://localhost:90——Kestrel仅绑定了容器内部的回环地址,外部请求无法穿透到容器内的应用。这是因为应用自身的配置(如appsettings.json、Program.cs中的Kestrel硬编码设置)覆盖了Docker传递的环境变量和命令行参数。
具体修复步骤
检查应用配置文件
打开appsettings.json或appsettings.Development.json,确认是否存在绑定localhost的配置:"Kestrel": { "Endpoints": { "Http": { "Url": "http://localhost:90" } } }若存在,将
Url修改为http://+:90,让Kestrel监听所有网络接口。修改Program.cs中的Kestrel配置
如果代码中硬编码了监听地址,找到类似代码:builder.WebHost.ConfigureKestrel(options => { options.ListenLocalhost(90); });修改为监听所有接口:
builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(90); // 监听所有IP的90端口 });或改为依赖配置文件/环境变量,避免硬编码:
builder.WebHost.UseKestrel();重新编译构建镜像
修改配置后重新发布应用,再执行构建和启动命令:docker build -t wetter_api_test . docker run --rm -it -p 80:90 wetter_api_test验证监听地址
容器启动后,确认日志显示Now listening on: http://[::]:90或http://+:90,而非http://localhost:90,此时外部即可通过http://localhost:80/swagger/index.html访问。
内容的提问来源于stack exchange,提问作者Rikero

