Popular blog tags

在 Windows 10 上开发 C#,手工制作 Linux Docker 镜像(amd64,Ubuntu 22.04)

Published

 

Windows 10 写 C# project→ dotnet publish linux-x64 → Ubuntu 22.04 Dockerfile → amd64 镜像

项目结构

MyApp/
├─ MyApp.csproj
├─ Program.cs
├─ Dockerfile
└─ bin/Release/net8.0/linux-x64/publish/
   └─ MyApp

 

 

 

用 自包含 Linux 版本

这样 Docker 镜像 不依赖宿主 .NET Runtime,最稳

dotnet publish \
  -c Release \
  -r linux-x64 \
  --self-contained true \
  /p:PublishSingleFile=true \
  /p:PublishTrimmed=false

output

bin/Release/net8.0/linux-x64/publish/

 

Dockerfile

 

 

# ===============================
# build stage - build 阶段
# ===============================
# 使用 官方 .NET SDK 镜像,SDK 镜像里已经有:dotnet MSBuild NuGet,不用自己装;jammy = Ubuntu 22.04;AS build:给这个阶段起名
FROM mcr.microsoft.com/dotnet/sdk:8.0-jammy AS build

# 容器内当前工作目录是 /src,相当于cd /src
WORKDIR /src

# 把 整个项目源码 拷贝进容器;如果没有 .dockerignore,bin/ obj/ 都会进来,CI 会非常慢
COPY . .

RUN dotnet publish \
    -c Release \
    -r linux-x64 \
    --self-contained true \
    -o /out

# ===============================
# runtime stage - build 阶段
# ===============================

# 运行环境
FROM ubuntu:22.04

# 禁止 apt 弹交互式界面,否则zdata 安装卡住 CI,构建永远不结束
ENV DEBIAN_FRONTEND=noninteractive

# 运行的时候目录,程序、配置、日志都会在这里
WORKDIR /app

# 更新软件源索引;HTTPS 访问必需ca-certificates;时区支持tzdata
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        tzdata \
    && rm -rf /var/lib/apt/lists/*    #  清理缓存,否则镜像会大 30–50MB

# 从 build 阶段拷贝 /out 到当前 /app,不带源码,只带运行文件
COPY --from=build /out .

# 给可执行权限
RUN chmod +x ./MyApp

# 容器默认用 5000 端口,映射要用 -p
EXPOSE 5000

# 容器启动即执行
ENTRYPOINT ["./MyApp"]

基础镜像

.NET 官方基础镜像,都来自微软官方仓库:仓库地址:mcr.microsoft.com/dotnet/

 

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

给阶段命名(build、builder、publish 等)

FROM mcr.microsoft.com/dotnet/sdk:8.0  

Linux Debian + .NET SDK + .NET runtime + ASP.NET runtime;SDK 会被打包进最终镜像,镜像会非常大(600~800MB)

mcr.microsoft.com/dotnet/runtime:8.0  - Linux Debian + .NET runtime

mcr.microsoft.com/dotnet/aspnet:8.0 -  

 

FROM mcr.microsoft.com/dotnet/runtime-deps:8.0

FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine

FROM mcr.microsoft.com/dotnet/runtime-deps:8.0

 

.Net 10 docker images

从 .NET 10 开始,微软官方将 Linux 基础镜像从 Debian 切换为了 Ubuntu(为了更好地匹配 .NET LTS 3年的生命周期)。因此,官方镜像名中不再频繁包含 debian 字样,默认对应的就是 Ubuntu

 

 Architectural Layering for .Net 10 docker images

+-------------------------------------------------------------+

|              ASP.NET Core Runtime (:10.0)                   |
|  (Includes Kestrel, HTTP/3, Routing, Data Protection, etc.) |
+-------------------------------------------------------------+
                              ||
                              \/ Inherits From
+-------------------------------------------------------------+

|                 .NET Runtime (:10.0)                        |
|  (Includes CoreCLR, Garbage Collector, JIT, Base Libraries) |
+-------------------------------------------------------------+
                              ||
                              \/ Inherits From
+-------------------------------------------------------------+

|               Runtime Dependencies (:10.0-deps)             |
|  (Native Linux OS packages: glibc, libssl, libicu, zlib)    |
+-------------------------------------------------------------+
                              ||
                              \/ Inherits From
+-------------------------------------------------------------+

|                 Base Linux OS (Ubuntu 24.04)                |
+-------------------------------------------------------------+

 

0.. NET 运行时依赖镜像 ( .NET Runtime Dependencies Image )

一个「完全不包含 .NET」的 .NET 官方镜像。
包含内容:它不包含 SDK 编译工具,不包含 .NET 运行时 (CLR),也不包含 ASP.NET Core。它仅仅包含了 .NET 程序在 Linux 系统上运行所必需的底层系统依赖库(如 glibc、libssl、zlib、crypto 等)。
镜像体积:极小。基于 Ubuntu Chiseled 版本的体积仅有 几十 MB 左右

 

1. SDK 编译镜像(开发/构建阶段使用)

 

2 .NET 基础运行镜像(非 Web 应用使用)

mcr.microsoft.com/dotnet/runtime:10.0

Target:Backend workers, background services, CLI tools.

3. ASP.NET Core 运行镜像(生产运行阶段使用)

mcr.microsoft.com/dotnet/aspnet:10.0

aspnet:10.0 is built directly on top of runtime:10.0, adding the necessary layers required to listen to internet traffic and handle web requests.

Target:Web APIs, Minimal APIs, Blazor, gRPC, MVC websites.

 

Official .NET Docker images

Microsoft Artifact Registry:https://mcr.microsoft.com/

 

.NET 10 :无 Dockerfile 容器化

 

如果不喜欢维护 Dockerfile,.NET 10 的 SDK 已经原生支持将应用直接打包成 OCI / Docker 容器镜像。

step 1.需要在你的项目文件 (.csproj) 中加入一行配置:

<PropertyGroup>
  <!-- 允许直接将当前项目打包为容器 -->
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>

 

step 2.

然后直接在本地或 CI/CD 命令行中执行以下命令,.NET 10 SDK 就会在后台自动采用最佳的多阶段精简模式帮你生成最终的镜像,完全不会把 SDK 本身打包进去

dotnet publish -c Release /p:PublishContainer=true

 

 .NET 10 的 Native AOT

对 .NET 10 的 Native AOT(原生提前编译) 部署,使用 AOT 可以将镜像进一步压缩到仅有 几十 MB 且无需任何 .NET 运行时基础镜像