Azure Pipelines 與 Docker 入門

本指南由社群貢獻。Docker 在此感謝 Kristiyan Velkov 的寶貴貢獻。

先決條件

在開始之前,請確保您滿足以下要求:

概述

本指南將引導您使用 Azure Pipelines 構建和推送 Docker 映象,為容器化應用程式實現精簡且安全的 CI 工作流。您將學習如何:

  • 安全地配置 Docker 身份驗證。
  • 設定自動化管道以構建和推送映象。

設定 Azure DevOps 以與 Docker Hub 配合使用

步驟 1:配置 Docker Hub 服務連線

要使用 Azure Pipelines 安全地對 Docker Hub 進行身份驗證:

  1. 在您的 Azure DevOps 專案中,導航到 Project Settings > Service Connections
  2. 選擇 New service connection > Docker Registry
  3. 選擇 Docker Hub 並提供您的 Docker Hub 憑據或訪問令牌。
  4. 為服務連線指定一個易於識別的名稱,例如 my-docker-registry
  5. 為提高安全性和遵循最小許可權原則,僅授予特定需要的管道訪問許可權。
重要

除非絕對必要,否則避免選擇授予所有管道訪問許可權的選項。始終應用最小許可權原則。

步驟 2:建立您的管道

將以下 azure-pipelines.yml 檔案新增到您的倉庫根目錄:

# Trigger pipeline on commits to the main branch
trigger:
  - main

# Trigger pipeline on pull requests targeting the main branch
pr:
  - main

# Define variables for reuse across the pipeline
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)

          # Optional: logout for self-hosted agents
          - script: docker logout
            displayName: Docker Logout (Self-hosted only)
            condition: ne(variables['Agent.OS'], 'Windows_NT')

此管道的作用

此管道為主分支自動化了 Docker 映象的構建和部署過程。它透過快取、標記和有條件的清理等最佳實踐,確保了安全高效的工作流。它的作用如下:

  • 在針對 main 分支的提交和拉取請求時觸發。
  • 使用 Azure DevOps 服務連線安全地對 Docker Hub 進行身份驗證。
  • 使用 Docker BuildKit 構建和標記 Docker 映象以進行快取。
  • 將 buildId 和 latest 標籤都推送到 Docker Hub。
  • 如果在自託管的 Linux 代理上執行,則從 Docker 登出。

管道如何工作

步驟 1:定義管道觸發器

trigger:
  - main

pr:
  - main

此管道會在以下情況下自動觸發:

  • 推送到 main 分支的提交
  • 針對 main 分支的拉取請求
提示

步驟 2:定義通用變數

variables:
  imageName: 'docker.io/$(dockerUsername)/my-image'
  buildTag: '$(Build.BuildId)'
  latestTag: 'latest'

這些變數確保了在整個管道步驟中命名、版本控制和重用的一致性:

  • imageName:您在 Docker Hub 上的映象路徑
  • buildTag:每次管道執行的唯一標籤
  • latestTag:您最新映象的穩定別名
重要

變數 dockerUsername 不會自動設定。
在您的 Azure DevOps 管道變數中安全地設定它:

  1. 前往 Pipelines > Edit > Variables
  2. 新增 dockerUsername 並填入您的 Docker Hub 使用者名稱

瞭解更多:在 Azure Pipelines 中定義和使用變數

步驟 3:定義管道階段和作業

stages:
  - stage: BuildAndPush
    displayName: Build and Push Docker Image

此階段僅在源分支是 main 時執行。

提示

步驟 4:作業配置

jobs:
  - job: DockerJob
  displayName: Build and Push
  pool:
    vmImage: ubuntu-latest
    demands:
      - docker

此作業利用了由 Microsoft 託管代理提供的最新 Ubuntu 虛擬機器映象,該映象支援 Docker。如有需要,可以用自定義池替換為自託管代理。

提示

步驟 4.1:檢出程式碼

steps:
  - checkout: self
    displayName: Checkout Code

此步驟將您的倉庫程式碼拉取到構建代理中,以便管道可以訪問 Dockerfile 和應用程式檔案。

提示

瞭解更多: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 登錄檔服務連線進行安全身份驗證,而無需直接暴露憑據。

提示

步驟 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) 以實現供應鏈透明度
  • 來源證明,以驗證映象是如何以及在何處構建的
提示

步驟 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 和證明構建滿足現代軟體供應鏈要求的映象

瞭解更多