Skip to main content

Docker 이미지 게시

CI(연속 통합) 워크플로의 일부로 Docker Hub 또는 GitHub Packages와 같은 레지스트리에 Docker 이미지를 게시할 수 있습니다.

소개

이 가이드에서는 Docker 빌드를 수행하는 워크플로를 만든 다음, Docker 이미지를 Docker Hub 또는 GitHub Packages에 게시하는 방법을 보여 줍니다. 단일 워크플로를 사용하여 단일 레지스트리 또는 여러 레지스트리에 이미지를 게시할 수 있습니다.

참고: 다른 타사 Docker 레지스트리로 푸시하려는 경우 “GitHub Packages에 이미지 게시” 섹션의 예제가 좋은 템플릿으로 사용될 수 있습니다.

필수 조건

워크플로 구성 옵션과 워크플로 파일을 만드는 방법을 기본적으로 이해하는 것이 좋습니다. 자세한 내용은 "워크플로 작성"을(를) 참조하세요.

또한 다음 사항을 기본적으로 이해하는 것이 유용할 수 있습니다.

이미지 구성 정보

이 가이드에서는 GitHub 리포지토리에 저장된 Docker 이미지에 대한 완전한 정의가 있다고 가정합니다. 예를 들어 리포지토리에는 Dockerfile 및 이미지를 만들기 위해 Docker 빌드를 수행하는 데 필요한 다른 파일이 포함되어야 합니다.

미리 정의된 주석 키로 설명, 라이선스 및 원본 리포지토리를 포함한 메타데이터를 컨테이너 이미지에 추가할 수 있습니다. 자세한 내용은 "컨테이너 레지스트리 작업.

이 가이드에서는 Docker build-push-action 작업을 사용하여 Docker 이미지를 빌드하고 하나 이상의 Docker 레지스트리에 푸시합니다. 자세한 내용은 build-push-action를 참조하세요.

Docker Hub에 이미지 게시

GitHub Enterprise Cloud에서 새 릴리스를 만들 때마다 워크플로를 트리거하여 이미지를 게시할 수 있습니다. 아래 예제의 워크플로는 release 이벤트가 published 활동 형식으로 트리거될 때 실행됩니다.

아래 예제 워크플로에서는 Docker login-actionbuild-push-action 작업을 사용하여 Docker 이미지를 빌드하고 빌드에 성공하면 빌드된 이미지를 Docker Hub로 푸시합니다.

Docker Hub로 푸시하려면 Docker Hub 계정이 있어야 하고 Docker Hub 리포지토리를 만들어야 합니다. 자세한 내용은 Docker 설명서에서 "Docker Hub로 Docker 컨테이너 이미지 푸시"를 참조하세요.

Docker Hub에 필요한 login-action 옵션은 다음과 같습니다.

  • usernamepassword: Docker Hub 사용자 이름 및 암호입니다. 워크플로 파일에 노출되지 않도록 Docker Hub 사용자 이름과 암호는 비밀로 저장하는 것이 좋습니다. 자세한 내용은 "GitHub Actions에서 비밀 사용"을(를) 참조하세요.

Docker Hub에 필요한 metadata-action 옵션은 다음과 같습니다.

  • images: Docker Hub로 빌드/푸시하는 Docker 이미지의 네임스페이스 및 이름입니다.

Docker Hub에 필요한 build-push-action 옵션은 다음과 같습니다.

  • tags: DOCKER-HUB-NAMESPACE/DOCKER-HUB-REPOSITORY:VERSION 형식의 새 이미지 태그입니다. 아래 표시된 것처럼 단일 태그를 설정하거나 목록에서 여러 태그를 지정할 수 있습니다.
  • push: true로 설정하면 이미지가 성공적으로 빌드된 경우 레지스트리에 푸시됩니다.
YAML
# 이 워크플로는 GitHub에서 인증되지 않은 작업을 사용합니다.
# 작업은 타사에서 제공하며
# 별도의 서비스 약관, 개인정보처리방침, 지원 설명서에서 규정됩니다.
# 참조하세요.

# 커밋 SHA에 작업을 고정하는 것이 좋습니다.
# 최신 버전을 얻으려면 SHA를 업데이트해야 합니다.
# 태그 또는 분기를 참조할 수도 있지만 경고 없이 작업이 변경될 수 있습니다.

name: Publish Docker image

on:
  release:
    types: [published]

jobs:
  push_to_registry:
    name: Push Docker image to Docker Hub
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
      attestations: write
      id-token: write
    steps:
      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: my-docker-hub-namespace/my-docker-hub-repository

      - name: Build and push Docker image
        id: push
        uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

      - name: Generate artifact attestation
        uses: actions/attest-build-provenance@v1
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

위의 워크플로는 GitHub 리포지토리를 체크 아웃하고 login-action을 사용하여 레지스트리에 로그인한 다음 build-push-action 작업을 사용하여 리포지토리의 Dockerfile을 기반으로 Docker 이미지를 빌드하고, 이미지를 Docker Hub로 푸시하고, 이미지에 태그를 적용합니다.

마지막 단계에서는 이미지에 대한 아티팩트 증명을 생성하여 공급망 보안을 강화합니다. 자세한 내용은 "아티팩트 증명을 사용하여 빌드의 출처 설정"을(를) 참조하세요.

GitHub Packages에 이미지 게시

GitHub Enterprise Cloud에서 새 릴리스를 만들 때마다 워크플로를 트리거하여 이미지를 게시할 수 있습니다. 아래 예제의 워크플로는 변경 내용이 release 분기에 푸시될 때 실행됩니다.

아래 예제 워크플로에서는 Docker login-action, metadata-action, 및 build-push-action 작업을 사용하여 Docker 이미지를 빌드하고 빌드에 성공하면 빌드된 이미지를 GitHub Packages에 푸시합니다.

GitHub Packages에 필요한 login-action 옵션은 다음과 같습니다.

  • registry: ghcr.io으로 설정해야 합니다.
  • username: ${{ github.actor }} 컨텍스트를 사용하여 워크플로 실행을 트리거한 사용자의 사용자 이름을 자동으로 사용할 수 있습니다. 자세한 내용은 "Accessing contextual information about workflow runs"을(를) 참조하세요.
  • password: 자동으로 생성된 GITHUB_TOKEN 비밀을 암호에 사용할 수 있습니다. 자세한 내용은 "자동 토큰 인증"을(를) 참조하세요.

GitHub Packages에 필요한 metadata-action 옵션은 다음과 같습니다.

  • images: 빌드 중인 Docker 이미지의 네임스페이스 및 이름입니다.

GitHub Packages에 필요한 build-push-action 옵션은 다음과 같습니다.

  • context: 지정된 경로에 있는 파일 집합으로 빌드의 컨텍스트를 정의합니다.
  • push: true로 설정하면 이미지가 성공적으로 빌드된 경우 레지스트리에 푸시됩니다.
  • tagslabels: metadata-action의 출력으로 채워집니다.

참고:

  • GitHub에서 인증되지 않은 작업을 사용하는 워크플로입니다. 타사에서 제공하며 별도의 서비스 약관, 개인 정보 보호 정책 및 지원 문서가 적용되는 작업입니다.
  • GitHub은(는) 커밋 SHA에 작업을 고정하는 것을 권장합니다. 최신 버전을 얻으려면 SHA를 업데이트해야 합니다. 태그 또는 분기를 참조할 수도 있지만 경고 없이 작업이 변경될 수 있습니다.
YAML
name: Create and publish a Docker image
on:
  push:
    branches: ['release']

Configures this workflow to run every time a change is pushed to the branch called release.

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest

There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.

    permissions:
      contents: read
      packages: write
      attestations: write
      id-token: write

Sets the permissions granted to the GITHUB_TOKEN for the actions in this job.

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Log in to the Container registry
        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

Uses the docker/login-action action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

This step uses docker/metadata-action to extract tags and labels that will be applied to the specified image. The id "meta" allows the output of this step to be referenced in a subsequent step. The images value provides the base name for the tags and labels.

      - name: Build and push Docker image
        id: push
        uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

This step uses the docker/build-push-action action to build the image, based on your repository's Dockerfile. If the build succeeds, it pushes the image to GitHub Packages. It uses the context parameter to define the build's context as the set of files located in the specified path. For more information, see "Usage" in the README of the docker/build-push-action repository. It uses the tags and labels parameters to tag and label the image with the output from the "meta" step.

      - name: Generate artifact attestation
        uses: actions/attest-build-provenance@v1
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see "아티팩트 증명을 사용하여 빌드의 출처 설정."

#
name: Create and publish a Docker image

# Configures this workflow to run every time a change is pushed to the branch called `release`.
on:
  push:
    branches: ['release']

# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
    permissions:
      contents: read
      packages: write
      attestations: write
      id-token: write
      # 
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here.
      - name: Log in to the Container registry
        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
      # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
      # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
      # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
      - name: Build and push Docker image
        id: push
        uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
      
      # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)." 
      - name: Generate artifact attestation
        uses: actions/attest-build-provenance@v1
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true
      

위의 워크플로는 “릴리스” 분기로 푸시하여 트리거됩니다. GitHub 리포지토리를 확인하고 login-action을 사용하여 Container registry에 로그인합니다. 그런 다음 Docker 이미지에 대한 레이블 및 태그를 추출합니다. 최종적으로, build-push-action 작업을 사용하여 이미지를 빌드하고 Container registry에 게시합니다.

Docker Hub 및 GitHub Packages에 이미지 게시

단일 워크플로에서 각 레지스트리에 login-actionbuild-push-action 작업을 사용하여 여러 레지스트리에 Docker 이미지를 게시할 수 있습니다.

다음 예제 워크플로는 이전 섹션의 단계(“Docker Hub 이미지 게시” 및 “GitHub Packages에 이미지 게시”)를 사용하여 두 레지스트리에 푸시하는 단일 워크플로를 만듭니다.

YAML
# 이 워크플로는 GitHub에서 인증되지 않은 작업을 사용합니다.
# 작업은 타사에서 제공하며
# 별도의 서비스 약관, 개인정보처리방침, 지원 설명서에서 규정됩니다.
# 참조하세요.

# 커밋 SHA에 작업을 고정하는 것이 좋습니다.
# 최신 버전을 얻으려면 SHA를 업데이트해야 합니다.
# 태그 또는 분기를 참조할 수도 있지만 경고 없이 작업이 변경될 수 있습니다.

name: Publish Docker image

on:
  release:
    types: [published]

jobs:
  push_to_registries:
    name: Push Docker image to multiple registries
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
      attestations: write
      id-token: write
    steps:
      - name: Check out the repo
        uses: actions/checkout@v4

      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Log in to the Container registry
        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
        with:
          images: |
            my-docker-hub-namespace/my-docker-hub-repository
            ghcr.io/${{ github.repository }}

      - name: Build and push Docker images
        id: push
        uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

      - name: Generate artifact attestation
        uses: actions/attest-build-provenance@v1
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

위의 워크플로는 GitHub Enterprise Cloud 리포지토리를 체크 아웃하고, login-action을 두 번 사용하여, 두 레지스트리에 모두 로그인하고 metadata-action 작업으로 태그와 레이블을 생성합니다. 그러면 build-push-action 작업이 Docker 이미지를 빌드하여 Docker Hub 및 Container registry(으)로 푸시합니다.

마지막 단계에서는 이미지에 대한 아티팩트 증명을 생성하여 공급망 보안을 강화합니다. 자세한 내용은 "아티팩트 증명을 사용하여 빌드의 출처 설정"을(를) 참조하세요.