Docker + Debian 运行 .NET 10 环境

本文档详细介绍如何在Debian Docker容器中部署和运行.NET 10应用程序。

一、环境准备

1.1 拉取Debian基础镜像

docker pull debian

1.2 下载.NET 10 SDK

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。

迁移步骤:

  1. 更换NuGet包
<!-- 移除 -->
<PackageReference Include="MySql.EntityFrameworkCore" Version="..." />

<!-- 添加 -->
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
  1. 修改DbContext配置
optionsBuilder.UseNpgsql(connectionString);
  1. 调整连接字符串
# 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 中使用缓存

九、安全最佳实践

  1. 避免使用特权模式:除非绝对必要
  2. 使用非root用户:在容器内以非root用户运行应用
  3. 最小化暴露端口:仅暴露必要的端口
  4. 使用Docker Secrets:管理敏感信息
  5. 定期更新镜像:保持基础镜像和依赖库为最新版本
  6. 使用 chiseled 镜像:生产环境推荐使用 -noble-chiseled 标签的镜像

posted on 2026-11-03 09:26  urmnur  阅读(2)  评论(0)    收藏  举报

导航