使用 dotnet publish 容器化 .NET 应用
容器具有许多功能和优势,例如不可变基础结构、提供可移植体系结构和实现可伸缩性。 该映像可用于为本地开发环境、私有云或公有云创建容器。 本教程介绍如何使用 dotnet publish 命令来容器化 .NET 应用程序,而无需使用 Dockerfile。 此外,还介绍了如何配置 容器映像 和执行,以及如何清理资源。
提示
如果有兴趣使用 Dockerfile 容器化 .NET 应用,请参阅 教程:容器化 .NET 应用。
先决条件
安装以下必备组件:
- .NET 8+ SDK
如果已安装 .NET,请使用dotnet --info
命令来确定所使用的 SDK。
如果计划在本地运行容器,则需要与开放容器计划(OCI)兼容的容器运行时,例如:
- Docker Desktop:最常见的容器运行时。
- Podman:一种无守护进程的开源 Docker 替代方案。
重要
.NET SDK 在不使用 Docker 的情况下创建容器映像。 仅当想要在本地运行映像时,才需要 Docker 或 Podman。 默认情况下,将 .NET 应用作为容器映像发布时,则会将其推送到本地容器运行时。 或者,可以将 映像保存为 tarball,或者直接将其推送到 容器注册表,而无需使用任何容器运行时。
除了这些先决条件之外,建议你熟悉 .NET 中的辅助角色服务,因为示例项目是一个辅助角色。
创建 .NET 应用
需要一个 .NET 应用来容器化,因此首先从模板创建新应用。 打开终端,创建工作文件夹(示例目录),如果尚未这样做,请更改目录,以便你位于其中。 在工作文件夹中运行以下命令,在名为 Worker的子目录中创建新项目:
dotnet new worker -o Worker -n DotNet.ContainerImage
文件夹树类似于以下目录:
📁 sample-directory
└──📂 Worker
├──appsettings.Development.json
├──appsettings.json
├──DotNet.ContainerImage.csproj
├──Program.cs
├──Worker.cs
├──📂 Properties
│ └─── launchSettings.json
└──📂 obj
├── DotNet.ContainerImage.csproj.nuget.dgspec.json
├── DotNet.ContainerImage.csproj.nuget.g.props
├── DotNet.ContainerImage.csproj.nuget.g.targets
├── project.assets.json
└── project.nuget.cache
dotnet new
命令创建一个名为 辅助角色 的新文件夹,并生成一个辅助角色服务,该服务在运行时每隔一秒记录一条消息。 从终端会话,更改目录并导航到 Worker 文件夹。 使用 dotnet run
命令启动应用。
dotnet run
Using launch settings from ./Worker/Properties/launchSettings.json...
Building...
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:28 -06:00
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: .\Worker
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:29 -06:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:30 -06:00
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
辅助角色模板无限期循环。 使用 cancel 命令 Ctrl+C 停止它。
设置容器映像名称
将应用发布为容器时,可以使用各种配置选项。 默认情况下,容器映像名称是项目的 AssemblyName
。 如果该名称作为容器映像名称无效,可以通过指定 ContainerRepository
来替代它,如以下项目文件中所示:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
<ContainerRepository>dotnet-worker-image</ContainerRepository>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.1" />
</ItemGroup>
</Project>
要获取进一步参考,请参阅 ContainerRepository
。
发布 .NET 应用
若要将 .NET 应用发布为容器,请使用以下 dotnet publish 命令:
dotnet publish --os linux --arch x64 /t:PublishContainer
前面的 .NET CLI 命令将应用发布为容器:
- 以 Linux 为目标,将其作为 OS (
--os linux
)。 - 指定 x64 体系结构(
--arch x64
)。
重要
若要在本地发布容器,必须运行一个符合 OCI 的正在运行的守护程序。 如果在尝试将应用作为容器发布时该应用未运行,您将遇到如下错误:
..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]
dotnet publish
命令生成类似于示例输出的输出:
Restore complete (0.2s)
DotNet.ContainerImage succeeded (2.6s) → bin\Release\net9.0\linux-x64\publish\
此命令将您的工作应用编译到 发布 文件夹,并默认将容器镜像推送到本地 Docker 守护程序。 如果使用的是 Podman,则为别名
将 .NET 应用发布到 tarball
tarball(或 tar 文件)是包含其他文件的文件。 它通常以 *.tar.gz复合文件扩展名结尾,以帮助指示它是压缩的存档。 这些文件类型用于分发软件或创建备份。 在这种情况下,创建的 tarball 用于分发容器映像。
若要将 .NET 应用作为容器发布到 tarball,请使用以下命令:
dotnet publish --os linux --arch x64 \
/t:PublishContainer \
-p ContainerArchiveOutputPath=./images/container-image.tar.gz
上述命令将应用作为容器发布到 tarball:
- 以 Linux 为目标,将其作为 OS (
--os linux
)。 - 指定 x64 体系结构(
--arch x64
)。 - 将
ContainerArchiveOutputPath
属性设置为./images/container-image.tar.gz
。
该命令不需要运行符合 OCI 的守护程序。 有关详细信息,请参阅 ContainerArchiveOutputPath
。
加载 tarball
导出到 tarball 的一个常见用例是面向以安全为重点的组织。 他们创建容器,将其导出为 tarball 文件,然后对这些 tarball 文件运行安全扫描工具。 此方法简化了合规性,因为它避免了扫描实时系统的复杂性。
tarball 包含整个容器,然后可以使用适当的工具加载:
- Docker:
docker load -i ./images/container-image.tar.gz
- Podman:
podman load -i ./images/container-image.tar.gz
将 .NET 应用发布到容器注册表
容器注册表是存储和管理容器映像的服务。 它们用于在多个环境中存储和分发容器映像。 可以使用以下命令将 .NET 应用作为容器发布到容器注册表:
dotnet publish --os linux --arch x64 \
/t:PublishContainer \
-p ContainerRegistry=ghcr.io
前面的代码将应用作为容器发布到容器注册表:
- 将 Linux 设定为目标操作系统(
--os linux
)。 - 指定 x64 体系结构(
--arch x64
)。 - 将
ContainerRegistry
属性设置为ghcr.io
。
有关详细信息,请参阅 ContainerRegistry。
清理资源
在本文中,你已将 .NET 辅助角色作为容器映像发布。 如果需要,请删除此资源。 使用 docker images
命令查看已安装映像的列表。
docker images
请考虑以下示例输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
dotnet-worker-image 1.0.0 25aeb97a2e21 12 seconds ago 191MB
提示
图像文件可能很大。 通常,你将删除在测试和开发应用时创建的临时容器。 如果计划在相应运行时的基础之上生成其他映像,通常会将基础映像与运行时一同安装。
若要删除映像,请复制映像 ID 并运行 docker image rm
命令:
docker image rm 25aeb97a2e21