Docker + Debian 运行 .NET 10 环境
本文档详细介绍如何在Debian Docker容器中部署和运行.NET 10应用程序。
一、环境准备
1.1 拉取Debian基础镜像
docker pull debian
1.2 下载.NET 10 SDK
- 官方网站: https://dotnet.microsoft.com/zh-cn/download/dotnet/10.0
- 直接下载链接: https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/sdk-10.0.203-linux-x64-binaries
1.3 解压SDK文件
mkdir -p /home/debian/.NET10/SDK
tar zxf dotnet-sdk-10.0.203-linux-x64.tar.gz -C /home/debian/.NET10/SDK
目录结构建议:
/home/debian/
├── .NET10/
│ └── SDK/ # .NET SDK运行时文件
├── K10/ # K10应用程序文件
│ ├── K10.PIM/
│ ├── K10.LCR/
│ └── ...
└── Test01/ # 测试应用
二、运行测试应用
docker run -it -d \
-e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true \
--name debian-test01 \
--privileged=true \
-v /home/debian/.NET10/SDK:/usr/local/dotnet \
-v /home/debian/Test01:/usr/local/app \
debian \
/usr/local/dotnet/dotnet /usr/local/app/Test01.dll
三、参数说明
| 参数 | 说明 |
|---|---|
-e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true |
设置环境变量,启用全球化不变模式,避免Linux缺少ICU库的问题 |
--name debian-test01 |
为容器命名 |
--privileged=true |
启用特权模式,赋予容器更多系统权限(谨慎使用) |
-v /home/debian/.NET10/SDK:/usr/local/dotnet |
挂载.NET SDK目录 |
-v /home/debian/Test01:/usr/local/app |
挂载应用程序目录 |
四、处理全球化问题
方法一:使用环境变量
-e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true
方法二:在代码中设置
System.AppContext.SetSwitch("System.Globalization.Invariant", true);
五、部署K10应用
运行K10.PIM服务
docker run -it -d \
--name K10.PIM \
--env TZ=Asia/Shanghai \
--privileged=true \
--log-opt max-size=10m \
--log-opt max-file=3 \
-p 51982:51982 \
-p 61982:61982 \
-v /home/debian/.NET10/SDK:/usr/local/dotnet \
-v /home/debian/K10:/usr/local/app \
--restart always \
debian \
/usr/local/dotnet/dotnet /usr/local/app/K10.PIM/K10.dll
运行K10.LCR服务
docker run -it -d \
--name K10.LCR \
--env TZ=Asia/Shanghai \
--privileged=true \
--log-opt max-size=10m \
--log-opt max-file=3 \
-p 51010:51010 \
-p 61010:61010 \
-v /home/debian/.NET10/SDK:/usr/local/dotnet \
-v /home/debian/K10:/usr/local/app \
--restart always \
debian \
/usr/local/dotnet/dotnet /usr/local/app/K10.LCR/K10.dll
六、数据库适配问题
MySQL到PostgreSQL迁移
由于 MySql.EntityFrameworkCore 对Linux支持存在兼容性问题,Pomelo.EntityFrameworkCore.MySql 没有.NET 10版本支持,因此决定改用PostgreSQL。
迁移步骤:
- 更换NuGet包
<!-- 移除 -->
<PackageReference Include="MySql.EntityFrameworkCore" Version="..." />
<!-- 添加 -->
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
- 修改DbContext配置
optionsBuilder.UseNpgsql(connectionString);
- 调整连接字符串
# PostgreSQL
Host=localhost;Database=mydb;Username=postgres;Password=mypassword;Port=5432
七、常见问题及解决方案
应用无法启动
- 检查.NET SDK路径
- 检查应用程序文件
- 查看容器日志:
docker logs K10.PIM
端口冲突
- 查看端口占用:
sudo netstat -tlnp | grep 51982 - 更改映射端口
数据库连接失败
- 检查PostgreSQL容器状态
- 测试数据库连接
八、推荐的 Dockerfile 方式(官方推荐)
.NET 10 默认使用 Ubuntu 作为基础镜像(Debian 镜像已不再提供),推荐使用多阶段构建的 Dockerfile:
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-chiseled AS production
WORKDIR /app
COPY --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["dotnet", "MyApp.dll"]
镜像选择指南:
| 场景 | Runtime Image | 压缩大小 | 说明 |
|---|---|---|---|
| 标准 ASP.NET | aspnet:10.0 |
~92 MB | Ubuntu 默认 |
| 更小体积 | aspnet:10.0-alpine |
~52 MB | Alpine Linux |
| 生产推荐 | aspnet:10.0-noble-chiseled |
~53 MB | 无shell、非root、安全加固 |
| Azure Linux | aspnet:10.0-azurelinux3.0-distroless |
~55 MB | Microsoft供应链安全 |
构建和运行:
docker build -t myapp:latest -f Dockerfile .
docker run -d -p 8080:8080 --restart always myapp:latest
8.2 Native AOT 编译(推荐用于高性能场景)
.NET 10 支持 Native AOT 编译,可以将应用编译为单一本地二进制文件,无需 .NET 运行时,启动速度更快,内存占用更低:
FROM mcr.microsoft.com/dotnet/sdk:10.0-noble-aot AS build
WORKDIR /src
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -r linux-x64 -o /app/publish \
/p:PublishAot=true \
/p:StripSymbols=true
FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled AS final
WORKDIR /app
COPY --from=build /app/publish .
USER app
EXPOSE 8080
ENTRYPOINT ["./MyApp"]
Native AOT 优势:
- 🚀 启动速度提升 10-50 倍(毫秒级启动)
- 📦 镜像体积减小约 50%(约 50MB)
- 💾 内存占用更低
注意事项:
- 需要在项目文件中启用 AOT:
<PublishAot>true</PublishAot> - 部分 .NET 特性不支持 AOT(反射、动态代码生成等)
- 编译时间较长,建议在 CI/CD 中使用缓存
九、安全最佳实践
- 避免使用特权模式:除非绝对必要
- 使用非root用户:在容器内以非root用户运行应用
- 最小化暴露端口:仅暴露必要的端口
- 使用Docker Secrets:管理敏感信息
- 定期更新镜像:保持基础镜像和依赖库为最新版本
- 使用 chiseled 镜像:生产环境推荐使用
-noble-chiseled标签的镜像
浙公网安备 33010602011771号