部署到容器和 Docker Hub - 用 C# 构建示例 API 课程
将 .NET Core 应用程序部署到 Docker 容器中是现代开发人员的一项重要技能。 容器提供了不可变的基础架构、易于分发和轻量级的运行时环境。 在本深度指南中,我们将按照 Tim Corey 的综合视频教程中演示的步骤,将示例 API 部署到 Docker 容器,然后推送到 Docker Hub:"Deploying to a Container and Docker Hub - Building a Sample API in C#".
让我们一步一步地探索翻译过程,同时参考具体的时间戳,以便于跟读。 本指南包括 dotnet publish、docker run 命令等命令的用法,以及基本映像、运行时映像和容器映像等术语,这些都是使用 Docker 部署 .NET 应用程序的重要概念。
创建和理解示例 API.
在视频的开头,蒂姆强调了在学习网络开发时示例应用程序的作用。 该应用程序包括 /courses 和 /health 等端点,可模拟真实世界中的问题,如健康检查功能降低,并可在本地计算机和远程服务器上运行。
这是一个 .NET Core 应用程序(更准确地说,是一个 ASP.NET Core 最小 API),可以通过 Docker 容器轻松运行和测试。
在本地设置 Docker.
Tim 使用 Docker Desktop 检查 Docker 是否安装在本地计算机上。他指出,可以在本地没有安装 Docker 的情况下直接发布到 Docker Hub,但为了演示,他还是从本地部署开始。
他展示了两个预装的 Docker 镜像:
个人字幕工具
- 微软官方 ASP.NET Core 基本图像:mcr.microsoft.com/dotnet/aspnet
该基础镜像约 328 MB,是我们容器镜像的基础。 微软在其 MCR(微软容器注册中心)上托管这些映像,它们同时支持 Linux 容器和 Windows 容器。 本项目的目标操作系统是 Linux。
本地发布到容器
Tim 浏览到 API 项目文件夹,并在命令行中运行以下命令:
dotnet publish -p:PublishProfile=DefaultContainerdotnet publish -p:PublishProfile=DefaultContainer该命令使用 .NET 8 和 .NET 9 中的内置容器支持,无需 Dockerfile。发布过程会选择一个合适的运行时映像,并构建一个独立的容器映像。
下面是引擎盖下发生的事情:
项目文件(.csproj)用于构建 API
使用 dotnet restore 命令恢复依赖关系
输出结果将存入发布文件夹
- 制作 DLL 文件并将其嵌入到容器中
最终生成的图像约为 333 MB(仅比基础图像大 5 MB)。
使用 Docker 运行映像
创建映像后,Tim 使用 Docker Desktop 运行容器。 在内部,应用程序通过 8080 端口监听。Tim 在端口配置中输入 0,将其映射为随机主机端口。
容器以随机名称(如 elegant_hoover)启动,浏览器打开后显示一个正在运行的 API,默认响应为 "Hello World"。
通过浏览 /courses 和 /health,Tim 可以确认 API 正在运行。 健康检查端点可用于模拟生产环境场景。
要查看正在运行的容器,可以使用 CLI 中的 docker ps 命令。 Tim 随后删除了正在运行的容器和镜像,以演示清理工作。
创建 Docker Hub 资源库
接下来,Tim 将介绍云部署部分。 他登录自己的 Docker Hub 账户,创建了一个名为 thesampleapi 的公共仓库。
这里将推送 Docker 镜像,以便其他人使用:
docker pull timcorey/thesampleapi:latestdocker pull timcorey/thesampleapi:latest为 Docker Hub 配置项目
在 API 的项目文件中,Tim 添加了元数据,以定义在哪里以及如何发布 Docker 镜像。 他添加了以下代码块:
<ContainerRegistry>docker.io</ContainerRegistry>
<ContainerRepository>timcorey/thesampleapi</ContainerRepository>
<ContainerImageTags>1.0.0;latest</ContainerImageTags><ContainerRegistry>docker.io</ContainerRegistry>
<ContainerRepository>timcorey/thesampleapi</ContainerRepository>
<ContainerImageTags>1.0.0;latest</ContainerImageTags>ContainerRegistry:指定 Docker Hub 为目标注册中心。
容器存储库:指向 Docker Hub repo 的路径。
- ContainerImageTags:为版本和最新发布的图像添加标签。
这将为将来的多阶段构建流程做好准备,不过 Tim 目前还是保持简单。
发布到 Docker Hub
蒂姆再次运行相同的发布命令:
dotnet publish -p:PublishProfile=DefaultContainerdotnet publish -p:PublishProfile=DefaultContainer最初,推送失败的原因是他忘记保存 .csproj 文件。保存并重新运行命令后,镜像成功上传到 Docker Hub。
在 Docker Hub 中,最新和 1.0.0 标签都出现在 thesampleapi repo 下。 在提取特定版本时,这些标签可以灵活使用。
从 Docker Hub 拉取映像
Tim 演示了如何从任何安装了 Docker 的机器上提取镜像:
docker pull timcorey/thesampleapi:latestdocker pull timcorey/thesampleapi:latest由于采用了 Docker 层缓存技术,图片下载速度很快,因为大部分内容都已经存在于基础图片中。
运行图像:
docker run -p 0:8080 timcorey/thesampleapi:latestdocker run -p 0:8080 timcorey/thesampleapi:latest将随机主机端口映射到内部端口 8080。
创建图像的新版本
为了演示版本控制,Tim 将 .csproj 文件编辑为
<ContainerImageTags>1.0.1;latest</ContainerImageTags><ContainerImageTags>1.0.1;latest</ContainerImageTags>然后,他重新运行发布命令:
dotnet publish -p:PublishProfile=DefaultContainerdotnet publish -p:PublishProfile=DefaultContainer现在,Docker Hub 存储库显示了三个标签:
1.0.0
1.0.1
- 最新(现在指向 1.0.1)
Tim 解释说,尽管有多个标签,但 Docker 不会存储重复的层,而是通过不同的层来优化磁盘使用。
使用 Docker Image 进行本地开发
Tim 强调说,一旦镜像放到 Docker Hub 上,您就可以随时在任何机器上运行它:
docker pull timcorey/thesampleapi:latestdocker pull timcorey/thesampleapi:latest然后使用 docker run 命令启动它。完成后,用以下工具进行清理:
docker ps # Get container ID
docker stop <id> # Stop the container
docker rm <id> # Remove the container
docker rmi <image> # Remove the imagedocker ps # Get container ID
docker stop <id> # Stop the container
docker rm <id> # Remove the container
docker rmi <image> # Remove the image他解释说,这使得它非常适合按需开发和测试,而不会使您的本地机器变得臃肿。
接下来是什么?
Tim 最后提到了下一步:将相同的 API 部署到虚拟专用服务器 (VPS)。 他将介绍如何映射一个域并配置容器,使其可以公开访问。
结论:从本地构建到云部署
利用 Tim Corey 的 视频指南,我们完成了以下工作:
使用 dotnet new 控制台构建 .NET Core API
使用 dotnet restore 和 dotnet publish 进行构建和部署
无需示例 Docker 文件即可创建 Docker 容器
将容器镜像上传到 Docker Hub
使用 docker run 拉出并运行容器
管理标签和不同的图像层
- 为使用版本化映像的生产环境而准备
该工作流程以 Docker 和 .NET 为中心,非常适合构建可扩展、可测试和可共享的应用程序。

