.NET Web API容器部署遇TLS连接与Socket错误求助
.NET Web API Docker容器请求失败问题排查与解决
问题现象
- 部署带天气预测功能的基础.NET Web API到Docker容器后,发送请求出现以下错误:
- 使用
GET https://localhost:8080/WeatherForecast时,报错:Client network socket disconnected before secure TLS connection was established - 使用
GET http://localhost:8080/WeatherForecast时,报错:socket hang up
- 使用
- 已排查:关闭防火墙、确认端口8080无占用、无代理/VPN,容器日志显示应用正常启动但未收到请求:
2024-01-27 19:14:36 info: Microsoft.Hosting.Lifetime[14] 2024-01-27 19:14:36 Now listening on: http://[::]:8080 2024-01-27 19:14:36 info: Microsoft.Hosting.Lifetime[0] 2024-01-27 19:14:36 Application started. Press Ctrl+C to shut down. 2024-01-27 19:14:36 info: Microsoft.Hosting.Lifetime[0] 2024-01-27 19:14:36 Hosting environment: Production 2024-01-27 19:14:36 info: Microsoft.Hosting.Lifetime[0] 2024-01-27 19:14:36 Content root path: /app
当前配置文件
docker-compose.yml
version: "3.9" networks: online-test-dev: driver: bridge services: app: container_name: online-test build: context: . dockerfile: Dockerfile ports: - "8080:80"
Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base USER app WORKDIR /app EXPOSE 80 EXPOSE 8080 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["WebApplication1/WebApplication1.csproj", "WebApplication1/"] RUN dotnet restore "./WebApplication1/./WebApplication1.csproj" COPY . . WORKDIR "/src/WebApplication1" RUN dotnet build "./WebApplication1.csproj" -c $BUILD_CONFIGURATION -o /app/build FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "./WebApplication1.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "WebApplication1.dll"]
WeatherForecastController代码
using Microsoft.AspNetCore.Mvc; namespace WebApplication1.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } } }
问题原因
从容器日志可以看到,应用在容器内部监听的是8080端口,但docker-compose.yml中的端口映射是"8080:80"——把宿主机的8080端口转发到容器的80端口,两者不匹配,导致请求无法到达应用。
另外,使用HTTPS请求报错是因为容器内的应用只配置了HTTP监听,没有启用HTTPS,直接用HTTPS访问会触发TLS连接失败。
解决方案
方案1:修正端口映射(推荐)
修改docker-compose.yml中的端口映射,将宿主机8080端口转发到容器的8080端口:
version: "3.9" networks: online-test-dev: driver: bridge services: app: container_name: online-test build: context: . dockerfile: Dockerfile ports: - "8080:8080" # 修正为宿主机8080 -> 容器8080
方案2:修改应用监听端口为80
如果希望应用在容器内监听80端口,可通过环境变量指定.NET应用的监听端口:
- 在
Dockerfile的final阶段添加环境变量:
FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENV ASPNETCORE_URLS=http://+:80 # 指定应用监听80端口 ENTRYPOINT ["dotnet", "WebApplication1.dll"]
- 保持
docker-compose.yml的端口映射"8080:80"不变。
验证步骤
- 停止并删除现有容器:
docker-compose down
- 重新构建并启动容器:
docker-compose up --build
- 使用HTTP请求访问:
curl http://localhost:8080/WeatherForecast
此时应能正常返回天气预测数据。
内容的提问来源于stack exchange,提问作者Maks Bubela
相关产品推荐
相关产品推荐

