使用 Microsoft Azure 将 ASP.NET Core Web 应用程序构建并部署为 Docker 容器 - 第 2 部分





5.00/5 (2投票s)
在本文中,我们将设置一个 Microsoft Azure DevOps 构建管道,以自动化本系列第一篇文章中手动完成的任务。
引言
这是本系列的第二篇文章。在这里,我们将设置一个 Microsoft Azure DevOps 构建管道,以自动化本系列第一篇文章中手动完成的任务。每次我们将更改推送到 master
分支时,都会触发构建以构建我们的应用程序,然后构建 Docker 镜像并将其推送到 Docker Hub。
如果您一直关注,那么您应该拥有
- 一个 GitHub 存储库
- 一个正常运行的 ASP.NET Core Web 应用程序(或类似应用程序)
- 应用程序的 Docker 镜像
- 一个正在运行的容器来本地托管您的应用程序
系列共三部分
- 开发一个 ASP.NET Core Web 应用程序并使用 Docker 对其进行容器化
- 使用 Microsoft Azure DevOps Pipeline 和 GitHub 设置持续集成
- 设置持续部署管道,将应用程序部署为 Azure Web 应用服务上的 Docker 容器
Docker 注册表
首先,您需要在 Docker Hub 上设置一个帐户。之后,创建一个存储库,您可以在其中存储应用程序的 Docker 镜像。
您已经有一个在之前步骤中构建的 Docker 镜像,它运行良好。所以现在,您可以使用存储库名称标记该镜像。但是,在推送镜像之前,运行在本地机器上的 Docker 客户端需要连接到 Docker Hub 帐户。
以下命令将本地镜像标记为 Docker Hub 存储库,授权 Docker 客户端,最后将镜像推送到 Docker Hub。
$ docker tag <image-name> <namespace>/<repository>:<tag>
// example
$ docker tag webapp quickdevnotes/webapp:v1
// login to your Docker Hub account
$ docker login
username:
password:
// push the to Docker Hub
$ docker push quickdevnotes/webapp:v1
引用请注意,我使用的是 Docker Hub 上的公共存储库。如果您使用的是私有存储库,那么您必须首先使用
docker login
命令登录,然后推送镜像。否则,推送将因授权错误而失败。
Azure DevOps - 项目
现在进入有趣的部分。要开始使用 Azure DevOps 管道,您首先需要一个用户帐户。如果您已经有一个帐户,那太好了,您可以立即开始,或者您可以在此处注册。
登录后,它会要求您创建一个组织以及您希望托管项目的位置。将其命名为您喜欢的任何名称,并选择适合您需求的区域
接下来,我们必须在组织下创建一个项目。从右上角选择 +创建项目,并提供所需的详细信息。
从“高级”部分,本系列的目的不需要任何东西。所以,我将选择权留给您。
持续集成(构建管道)
终于到了自动化手动步骤的时候了。从 管道 > 构建 中选择 新建管道。
您的代码在哪里?
Azure 管道首先需要连接到您的应用程序代码存储库。因此,在 连接 选项卡上,选择 GitHub,连接到您的 GitHub。
之后,您将收到 OAuth 身份验证提示,以授权 Azure Pipelines 访问 GitHub 存储库。根据需要授予授权并提供凭据。
选择存储库
授权完成后,您可以看到 GitHub 帐户中的存储库列表。从存储库列表中,选择您的应用程序存储库,然后会提示 安装 Azure Pipelines。使用“仅选择存储库”选项,然后从下拉列表中选择您的应用程序存储库。
如果您想为所有当前和未来的存储库安装 Azure Pipelines,请选择“所有存储库”并单击安装。
azure-pipelines.yml
Azure 管道足够智能,可以分析您的应用程序存储库并提供一个基本的 azure-pipelines.yml 文件。这个 yml 文件位于您的 GitHub 存储库的根目录,并被 Azure 构建管道用于执行特定任务,例如构建应用程序、执行测试、构建 Docker 镜像等等。
这是我的构建管道的 azure-pipelines.yml 文件。我知道,它可能令人不知所措;但当我们详细讨论每个任务后,一切都会变得清晰。
trigger:
- master
pool:
vmImage: 'Ubuntu-16.04'
variables:
imageName: 'quickdevnotes/webapp:$(build.buildNumber)'
steps:
- script: dotnet test WebApp.Tests/WebApp.Tests.csproj --logger trx
displayName: Run unit tests
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
- task: Docker@1
displayName: Build an image
inputs:
command: Build an image
containerregistrytype: Container Registry
dockerRegistryEndpoint: DockerHub
dockerFile: Dockerfile
imageName: $(imageName)
imageNamesPath:
restartPolicy: always
- task: Docker@1
displayName: Push an image
inputs:
command: Push an image
containerregistrytype: Container Registry
dockerRegistryEndpoint: DockerHub
dockerFile: Dockerfile
imageName: $(imageName)
imageNamesPath:
restartPolicy: always
引用请注意,为您的构建管道生成的文件将与您在此处看到的文件不同。这是因为我已经使用实现我们最终目标所需的任务更新了该文件。
CI 任务 - 近距离观察
让我们仔细看看上面构建文件中定义的任务。我们将保持在一个较高的级别,只是为了让本系列的事情简单化。
trigger:
- master
触发器指定推送哪个分支将触发持续集成管道运行。在我的例子中,它是 master
分支。
如果您想使用不同的分支,只需更改分支的名称。如果我们不指定任何分支,则推送到任何分支都将触发构建。
pool:
vmImage: 'Ubuntu-16.04'
以上几行说明了管道的作业/任务使用哪个代理池。
variables:
imageName: 'quickdevnotes/webapp:$(build.buildNumber)'
我们使用变量部分来声明我们想在管道中使用的任何变量。例如,我在这里创建一个变量 imageName
,它将设置为我想要创建的 Docker 镜像的名称。
持续集成最佳实践建议使用 $(build.buildNumber)
来标记您的 Docker 镜像。因为这使得更新或回滚任何更改变得容易。
- script: dotnet test WebApp.Tests/WebApp.Tests.csproj --logger trx
displayName: Run unit tests
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
我还为我的应用程序添加了一些基本的单元测试。通过上述脚本,这些测试将在每次运行构建时执行。我们还可以从这些测试运行中获取测试报告。
- task: Docker@1
displayName: Build an image
inputs:
command: Build an image
containerregistrytype: Container Registry
dockerRegistryEndpoint: DockerHub
dockerFile: Dockerfile
imageName: $(imageName)
imageNamesPath:
restartPolicy: always
- task: Docker@1
displayName: Push an image
inputs:
command: Push an image
containerregistrytype: Container Registry
dockerRegistryEndpoint: DockerHub
dockerFile: Dockerfile
imageName: $(imageName)
imageNamesPath:
restartPolicy: always
上述两个任务中的第一个任务,使用存储库根目录中可用的 Dockerfile 构建 Docker 镜像。构建镜像后,第二个任务将该镜像推送到 Docker Hub 上的存储库。
引用要了解有关不同任务和可用选项的更多信息,请参阅文档。
为了将镜像推送到您的 Docker Hub 存储库,运行在构建代理上的 Docker 客户端需要首先获得授权。这与您手动推送镜像时所做的类似。
- task: Docker@1
...
dockerRegistryEndpoint: DockerHub
...
dockerRegistryEndpoint
设置为一个 docker 注册表服务连接,该连接包含 Docker Hub 帐户的凭据,并用于授权。接下来让我们设置它。
Docker 注册表服务连接
从导航窗格的左下方,选择 项目设置。然后在 管道 下,选择 服务连接,您应该会看到您的 GitHub 连接。
要连接 Docker 注册表,单击 新建服务连接,然后从列表中选择 Docker 注册表。
在下一个对话框窗口中,选择 Docker Hub 作为注册表类型,并将 DockerHub(必须与构建任务中的 dockerRegistryEndpoint
相同)设置为连接名称。
然后,提供您的 Docker Hub 帐户的 Docker ID 和密码。电子邮件是可选的。请确保选中“允许所有管道使用此连接”。
您可以使用“验证此连接”链接来验证连接。点击“确定”,我们就可以开始了。
测试构建管道
我相信,到目前为止,您已经掌握了足够的信息来自定义您的持续集成管道。好的,现在是时候测试它是否符合我们的预期了。
转到 管道 > 构建,然后选择 队列 以排队构建。如果您没有遇到任何错误,您应该会看到正在进行的构建。这是我的构建管道成功构建后的输出
管道中的最后一个任务已成功将新构建的 Docker 镜像推送到 Docker Hub。请注意 image
标签,它等于上图中的构建编号
为了进行最后一次测试,请更改应用程序代码中的某些内容并将其推送到 master
分支。这将触发构建,您将看到提交消息作为构建标题
请注意构建描述如何告诉您构建触发器,这证明它不是手动触发器。
恭喜!!
结论
在本文中,我们已经成功设置了一个使用 Microsoft Azure DevOps 的持续集成构建管道。从构建 .NET Core Web 应用程序到设置 CI 管道,我们已经完成了一半。
接下来,我们将设置发布管道,将我们的应用程序作为 Docker 容器部署到 Azure Web App Service。这将非常有趣。