.net 5 web 应用 docker 部署性能媲美原生,关键在于:1. 选用 aspnet 或 runtime-deps 基础镜像;2. 发布启用 readytorun、自包含与 trim;3. kestrel 配置适配容器(如 minthreads、0.0.0.0 绑定);4. 容器运行时传入 dotnet_* 等环境变量对齐资源。

直接用 Docker 容器跑 .NET 5 Web 应用,性能不输原生部署,关键在镜像选择、运行时配置和容器资源协同。下面几步到位。
选对基础镜像:用 runtime-deps 或 aspnet 而非 sdk
.NET 5 应用发布后只需运行时,不需要编译工具链。用 mcr.microsoft.com/dotnet/aspnet:5.0(带 IIS/Kestrel 优化)或更轻量的 mcr.microsoft.com/dotnet/runtime-deps:5.0(仅系统依赖),避免把 SDK(sdk:5.0)打进生产镜像——体积大、攻击面宽、启动慢。
示例 Dockerfile 片段:
- FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime
- WORKDIR /app
- COPY ./publish/ .
- ENTRYPOINT ["dotnet", "MyApp.dll"]
发布前做 ReadyToRun + 自包含 + Trim
发布时启用提前编译(R2R)可减少 JIT 开销,自包含部署(--self-contained true)消除宿主环境依赖,配合 --trim 剪裁未用代码(注意兼容性,建议先测试):
- dotnet publish -c Release -r linux-x64 --self-contained true --trim true -p:PublishReadyToRun=true
实测在容器中冷启动快 30%~50%,内存占用更稳。
容器内 Kestrel 配置要“贴身”
Docker 默认限制 CPU 和内存,Kestrel 若没适配会误判资源、线程池过载。在 Program.cs 或 appsettings.json 中显式设置:
- 启用
ThreadPool.MinThreads(如设为 100),防请求排队 - 配置
Kestrel.ServerHeader = false减少响应头开销 - 绑定地址用
0.0.0.0:80(不是 localhost),否则容器内无法被外部访问 - 加
--no-http2参数(如不需要 HTTP/2)可小幅降 CPU
运行时加参数:让容器真正“懂” .NET
启动容器时传入环境变量,引导 .NET 运行时行为:
- DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1(禁用 ICU,减小 Alpine 镜像体积,中文需额外处理)
- ASPNETCORE_URLS=http://+:80(明确监听地址端口)
- DOTNET_THREAD_COUNT=4(匹配容器分配的 CPU 核数,防线程争抢)
- COMPlus_TieredCompilation=0(高并发稳定场景可关分层编译,降低首次请求延迟)
docker run 示例:
- docker run -e ASPNETCORE_URLS="http://+:80" -e DOTNET_THREAD_COUNT=2 -p 8080:80 --cpus="2" --memory="1g" myapp
不复杂但容易忽略——镜像精简、发布优化、Kestrel调参、容器资源对齐,四点串起来,.NET 5 Web 应用在 Docker 里就能跑出接近裸机的吞吐和延迟。











