Azure Pipelines와 Docker 소개

Azure Pipelines와 Docker 소개 (Introduction to Azure Pipelines with Docker)

Azure Pipelines를 사용해 Docker 이미지 빌드와 푸시를 자동화하는 방법을 설명하는 가이드예요.

출처: 문서

본문

이 가이드는 커뮤니티 기여 문서예요. Docker는 귀중한 기여를 해준 Kristiyan Velkov에게 감사드려요.

사전 요구사항 (Prerequisites)

시작하기 전에 다음 요구사항이 있는지 확인하세요:

개요 (Overview)

이 가이드에서는 Azure Pipelines를 사용해 Docker 이미지를 빌드하고 푸시하여 컨테이너화된 애플리케이션을 위한 간소화되고 안전한 CI 워크플로우를 가능하게 하는 방법을 안내해요. 다음을 배우게 됩니다:

  • Docker 인증을 안전하게 구성.
  • 이미지를 빌드하고 푸시하는 자동화된 파이프라인 설정.

Azure DevOps를 Docker Hub와 함께 작동하도록 설정하기 (Set up Azure DevOps to work with Docker Hub)

1단계: Docker Hub 서비스 연결 구성 (Step 1: Configure a Docker Hub service connection)

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단계: 파이프라인 만들기 (Step 2: Create your pipeline)

저장소 루트에 다음 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')

이 파이프라인이 하는 일 (What this pipeline does)

이 파이프라인은 main 분기에 대한 Docker 이미지 빌드 및 배포 과정을 자동화해요. 캐싱, 태깅, 조건부 정리 같은 모범 사례로 안전하고 효율적인 워크플로우를 보장해요. 이 파이프라인이 하는 일:

  • main 분기를 대상으로 하는 커밋과 pull request에서 트리거됩니다.
  • Azure DevOps 서비스 연결로 Docker Hub에 안전하게 인증합니다.
  • 캐싱을 위해 Docker BuildKit을 사용해 Docker 이미지를 빌드하고 태그합니다.
  • buildId와 latest 태그를 모두 Docker Hub에 푸시합니다.
  • 자체 호스팅 Linux 에이전트에서 실행되는 경우 Docker에서 로그아웃합니다.

파이프라인이 작동하는 방식 (How the pipeline works)

1단계: 파이프라인 트리거 정의 (Step 1: Define pipeline triggers)

trigger:
  - main

pr:
  - main

이 파이프라인은 다음에서 자동으로 트리거됩니다:

  • main 분기에 푸시된 커밋
  • main 분기를 대상으로 하는 pull request

팁: Azure Pipelines에서 파이프라인 트리거 정의하기에 대해 자세히 알아보세요.

2단계: 공통 변수 정의 (Step 2: Define common variables)

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

이 변수들은 파이프라인 단계 전반에서 일관된 명명, 버전 관리, 재사용을 보장해요:

  • imageName: Docker Hub의 이미지 경로.
  • buildTag: 각 파이프라인 실행에 대한 고유 태그.
  • latestTag: 가장 최근 이미지에 대한 안정적인 별칭.

중요: dockerUsername 변수는 자동으로 설정되지 않아요. Azure DevOps 파이프라인 변수에서 안전하게 설정하세요:

3단계: 파이프라인 스테이지 및 작업 정의 (Step 3: Define pipeline stages and jobs)

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

이 스테이지는 소스 분기가 main일 때만 실행됩니다.

팁: Azure Pipelines의 스테이지 조건에 대해 자세히 알아보세요.

4단계: 작업 구성 (Step 4: Job configuration)

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

이 작업은 Microsoft 호스팅 에이전트가 제공하는 Docker 지원이 있는 최신 Ubuntu VM 이미지를 사용해요. 필요하다면 자체 호스팅 에이전트를 위한 사용자 지정 풀로 교체할 수 있어요.

팁: 파이프라인에서 풀 지정에 대해 자세히 알아보세요.

4.1단계: 코드 체크아웃 (Step 4.1: Checkout code)

steps:
  - checkout: self
    displayName: Checkout Code

이 단계는 빌드 에이전트로 저장소 코드를 가져와서 파이프라인이 Dockerfile과 애플리케이션 파일에 접근할 수 있게 해요.

팁: checkout 단계 문서에 대해 자세히 알아보세요.

4.2단계: Docker Hub에 인증 (Step 4.2: Authenticate to Docker Hub)

- task: Docker@2
  displayName: Docker Login
  inputs:
    command: login
    containerRegistry: 'my-docker-registry'  # Replace with your service connection name

사전 구성된 Azure DevOps Docker 레지스트리 서비스 연결을 사용해 자격 증명을 직접 노출하지 않고 안전하게 인증해요.

팁: checkout 단계 문서에 대해 자세히 알아보세요.

4.3단계: Docker 이미지 빌드 (Step 4.3: Build the Docker image)

- 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

Docker BuildKit으로 이미지를 빌드해요. 제공되는 이점:

  • 두 개의 태그: 고유 Build ID와 latest 하나
  • 더 빠른 빌드와 효율적인 레이어 캐싱을 위한 Docker BuildKit 활성화
  • 가장 최근에 푸시된 latest 이미지에서 캐시 pull
  • 공급망 투명성을 위한 SBOM(Software Bill of Materials)

팁: Azure Pipelines용 Docker 작업 및 Docker SBOM Attestations에 대해 자세히 알아보세요.

4.4단계: Docker 이미지 푸시 (Step 4.4: Push the Docker image)

- task: Docker@2
  displayName: Push Docker Image
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
  inputs:
    command: push
    repository: $(imageName)
    tags: |
      $(buildTag)
      $(latestTag)

이 조건을 적용하면 파이프라인이 문제를 조기 감지하기 위해 매 실행마다 Docker 이미지를 빌드하지만, 변경 사항이 main 분기에 병합될 때만 레지스트리에 이미지를 푸시해요 — Docker Hub를 깔끔하고 집중적으로 유지해요.

이 명령은 두 태그를 모두 Docker Hub에 업로드해요:

  • $(buildTag)는 실행당 추적성을 보장합니다.
  • latest는 가장 최근 이미지 참조에 사용합니다.

팁: 파이프라인 의미론에 대한 자세한 내용은 Azure Pipelines 문서를 참조하세요.

요약 (Summary)

  • 내장 서비스 연결을 사용한 안전한 Docker 인증.
  • 코드 변경에 의해 트리거되는 자동화된 이미지 빌드 및 태깅.
  • Docker BuildKit 캐시를 활용한 효율적인 빌드.
  • 지속 에이전트에서 로그아웃을 통한 안전한 정리.
  • SBOM과 attestation으로 현대 소프트웨어 공급망 요구사항을 충족하는 이미지 빌드.

자세히 알아보기 (Learn more)

더 알아보기 (Learn more)