Azure Pipelines 与 Docker 入门
本文档为社区贡献。Docker 感谢 Kristiyan Velkov 的宝贵贡献。
前置条件
开始之前,请确保满足以下要求:
- 一个已生成访问令牌的 Docker Hub 账户。
- 一个活跃的 Azure DevOps 项目,并连接了 Git 仓库。
- 项目中包含一个有效的
Dockerfile,位于根目录或适当的构建上下文中。
概述
本指南将带你使用 Azure Pipelines 构建和推送 Docker 镜像,为容器化应用实现流畅且安全的 CI 工作流。你将学会:
- 安全配置 Docker 认证。
- 设置自动化流水线以构建和推送镜像。
配置 Azure DevOps 与 Docker Hub 集成
步骤 1:配置 Docker Hub 服务连接
为在 Azure Pipelines 中安全地认证 Docker Hub:
- 在 Azure DevOps 项目中导航至 Project Settings > Service Connections。
- 选择 New service connection > Docker Registry。
- 选择 Docker Hub,并提供你的 Docker Hub 凭据或访问令牌。
- 为服务连接起一个易识别的名称,例如
my-docker-registry。 - 仅授予需要的特定流水线访问权限,以提升安全性并遵循最小权限原则。
Important除非绝对必要,否则避免选择授予所有流水线访问权限的选项。始终应用最小权限原则。
步骤 2:创建流水线
在仓库根目录添加以下 azure-pipelines.yml 文件:
# 在提交到 main 分支时触发流水线
trigger:
- main
# 在针对 main 分支的拉取请求时触发流水线
pr:
- main
# 定义变量以便在流水线中复用
variables:
imageName: 'docker.io/$(dockerUsername)/my-image'
buildTag: '$(Build.BuildId)'
latestTag: 'latest'
stages:
- stage: BuildAndPush
displayName: Build and Push Docker Image
jobs:
- job: DockerJob
displayName: Build and Push
pool:
vmImage: ubuntu-latest
demands:
- docker
steps:
- checkout: self
displayName: Checkout Code
- task: Docker@2
displayName: Docker Login
inputs:
command: login
containerRegistry: 'my-docker-registry' # Service connection name
- task: Docker@2
displayName: Build Docker Image
inputs:
command: build
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)
dockerfile: './Dockerfile'
arguments: |
--sbom=true
--attest type=provenance
--cache-from $(imageName):latest
env:
DOCKER_BUILDKIT: 1
- task: Docker@2
displayName: Push Docker Image
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
inputs:
command: push
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)
# 可选:仅用于自托管代理的登出
- script: docker logout
displayName: Docker Logout (Self-hosted only)
condition: ne(variables['Agent.OS'], 'Windows_NT')此流水线的作用
此流水线自动化了 main 分支的 Docker 镜像构建和部署流程。它通过缓存、标签和条件清理等最佳实践,确保安全高效的流水线工作流。具体功能如下:
- 在向
main分支提交和拉取请求时自动触发。 - 使用 Azure DevOps 服务连接安全认证 Docker Hub。
- 使用 Docker BuildKit 构建和标记镜像,实现缓存优化。
- 推送 buildId 和 latest 两个标签到 Docker Hub。
- 如果在自托管 Linux 代理上运行,则登出 Docker。
流水线工作原理
步骤 1:定义流水线触发器
trigger:
- main
pr:
- main此流水线在以下情况自动触发:
- 推送到
main分支的提交 - 针对
main分支的拉取请求
Tip了解更多信息:在 Azure Pipelines 中定义流水线触发器
步骤 2:定义通用变量
variables:
imageName: 'docker.io/$(dockerUsername)/my-image'
buildTag: '$(Build.BuildId)'
latestTag: 'latest'这些变量确保流水线各步骤中命名、版本和复用的一致性:
imageName:Docker Hub 上的镜像路径buildTag:每次流水线运行的唯一标签latestTag:最新镜像的稳定别名
Important变量
dockerUsername不会自动设置。
请在 Azure DevOps 流水线变量中安全设置:
- 进入 Pipelines > Edit > Variables
- 添加
dockerUsername,值为你的 Docker Hub 用户名了解更多信息:在 Azure Pipelines 中定义和使用变量
步骤 3:定义流水线阶段和作业
stages:
- stage: BuildAndPush
displayName: Build and Push Docker Image此阶段仅在源分支为 main 时执行。
Tip了解更多信息:Azure Pipelines 中的阶段条件
步骤 4:作业配置
jobs:
- job: DockerJob
displayName: Build and Push
pool:
vmImage: ubuntu-latest
demands:
- docker此作业使用 Microsoft 托管代理提供的最新 Ubuntu 虚拟机镜像(支持 Docker)。如有需要,可替换为自定义池以使用自托管代理。
Tip了解更多信息:在流水线中指定池
步骤 4.1:检出代码
steps:
- checkout: self
displayName: Checkout Code此步骤将仓库代码拉取到构建代理中,以便流水线能够访问 Dockerfile 和应用文件。
Tip了解更多信息:checkout 步骤文档
步骤 4.2:认证 Docker Hub
- task: Docker@2
displayName: Docker Login
inputs:
command: login
containerRegistry: 'my-docker-registry' # Replace with your service connection name使用预配置的 Azure DevOps Docker 注册表服务连接进行安全认证,避免直接暴露凭据。
Tip了解更多信息:Docker Hub 的服务连接使用
步骤 4.3:构建 Docker 镜像
- task: Docker@2
displayName: Build Docker Image
inputs:
command: build
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)
dockerfile: './Dockerfile'
arguments: |
--sbom=true
--attest type=provenance
--cache-from $(imageName):latest
env:
DOCKER_BUILDKIT: 1此步骤构建镜像时包含:
- 两个标签:一个带唯一构建 ID,一个为 latest
- 启用 Docker BuildKit 以实现更快构建和高效层缓存
- 从最近推送的 latest 镜像拉取缓存
- 软件物料清单 (SBOM) 以提升供应链透明度
- 证明声明以验证镜像的构建方式和位置
Tip
步骤 4.4:推送 Docker 镜像
- task: Docker@2
displayName: Push Docker Image
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
inputs:
command: push
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)通过应用此条件,流水线在每次运行时都会构建 Docker 镜像以确保早期发现问题,但仅在更改合并到主分支时才将镜像推送到注册表——保持 Docker Hub 的整洁和专注。
这会将两个标签上传到 Docker Hub:
$(buildTag)确保每次运行的可追溯性。latest用于最新镜像引用。
步骤 4.5:登出 Docker(自托管代理)
- script: docker logout
displayName: Docker Logout (Self-hosted only)
condition: ne(variables['Agent.OS'], 'Windows_NT')在基于 Linux 的自托管代理上,流水线结束时执行 docker logout 以主动清理凭据,增强安全态势。
总结
通过此 Azure Pipelines CI 设置,你可以获得:
- 使用内置服务连接进行安全的 Docker 认证。
- 由代码变更触发的自动化镜像构建和标记。
- 利用 Docker BuildKit 缓存的高效构建。
- 在持久化代理上通过登出实现安全清理。
- 满足现代软件供应链要求的构建镜像,包含 SBOM 和证明声明。
了解更多信息
- Azure Pipelines 文档:配置和管理 Azure DevOps 中 CI/CD 流水线的综合指南。
- Azure Pipelines 的 Docker 任务:在 Azure Pipelines 中使用 Docker 任务构建和推送镜像的详细参考。
- Docker Buildx Bake:探索 Docker 的高级构建工具,适用于复杂的多阶段、多平台构建设置。另请参阅 Mastering Buildx Bake 指南 了解实用示例和最佳实践。
- Docker Build Cloud:了解 Docker 的托管构建服务,用于在云中实现更快、可扩展且多平台的镜像构建。