# Docker 이미지 게시

이 자습서에서는 CI(연속 통합) 워크플로의 일부로 Docker Hub 또는 GitHub Packages 같은 레지스트리에 Docker 이미지를 게시하는 방법을 알아봅니다.

## 서문

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

> \[!NOTE]
> 다른 타사 Docker 레지스트리로 푸시하려는 경우 [게시 이미지 GitHub Packages](#publishing-images-to-github-packages) 섹션의 예제가 좋은 템플릿으로 사용될 수 있습니다.

## 필수 구성 요소

워크플로 구성 옵션과 워크플로 파일을 만드는 방법을 기본적으로 이해하는 것이 좋습니다. 자세한 내용은 [워크플로 작성](/ko/enterprise-server@3.22/actions/how-tos/write-workflows)을(를) 참조하세요.

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

* [GitHub Actions에서 비밀 사용](/ko/enterprise-server@3.22/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)
* [워크플로에서 인증에 GITHUB\_TOKEN 사용](/ko/enterprise-server@3.22/actions/tutorials/authenticate-with-github_token)
* [Docker 레지스트리 작업](/ko/enterprise-server@3.22/packages/working-with-a-github-packages-registry/working-with-the-docker-registry)

## 이미지 구성 정보

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

미리 정의된 주석 키로 설명, 라이선스 및 원본 리포지토리를 포함한 메타데이터를 컨테이너 이미지에 추가할 수 있습니다. 자세한 내용은 [컨테이너 레지스트리 작업](/ko/enterprise-server@3.22/packages/working-with-a-github-packages-registry/working-with-the-container-registry#labelling-container-images)을 참조하세요.

이 가이드에서는 Docker `build-push-action` 작업을 사용하여 Docker 이미지를 빌드하고 하나 이상의 Docker 레지스트리에 푸시합니다. 자세한 내용은 [`build-push-action`](https://github.com/marketplace/actions/build-and-push-docker-images)를 참조하세요.

> \[!NOTE]
> GitHub Actions의 GitHub Enterprise Server은(는) GitHub.com 또는 GitHub Marketplace에 대한 작업에 대한 액세스가 제한될 수 있습니다. 자세한 내용은 [GitHub.com 작업에 대한 액세스 관리](/ko/enterprise-server@3.22/admin/managing-github-actions-for-your-enterprise/managing-access-to-actions-from-githubcom) 을 참조하고 사이트 관리자에게 문의하세요 GitHub Enterprise .

## Docker Hub 이미지 게시

> \[!NOTE]
> Docker Hub는 일반적으로 자체 호스팅 러너에서 작업에 영향을 미치는 밀어넣기 및 끌어오기 작업 모두에 속도 제한을 적용합니다. 그러나 GitHub 호스팅 러너는 GitHub 및 Docker 간의 규약에 따라 이러한 제한을 받지 않습니다.

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

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

Docker Hub 푸시하려면 Docker Hub 계정이 있어야 하고 Docker Hub 리포지토리를 만들어야 합니다. 자세한 내용은 Docker 설명서에서 [ Docker 컨테이너 이미지를 Docker Hub](https://docs.docker.com/docker-hub/quickstart/#step-3-build-and-push-an-image-to-docker-hub)에 게시하는 방법을 참조하세요.

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

* `username` 및 `password`: Docker Hub 사용자 이름과 암호입니다. 워크플로 파일에 노출되지 않도록 Docker Hub 사용자 이름과 암호를 비밀로 저장하는 것이 좋습니다. 자세한 내용은 [GitHub Actions에서 비밀 사용](/ko/enterprise-server@3.22/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)을(를) 참조하세요.

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

* `images`: Docker Hub에 빌드/푸시하는 Docker 이미지의 네임스페이스 및 이름.

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

* `tags`: `DOCKER-HUB-NAMESPACE/DOCKER-HUB-REPOSITORY:VERSION` 형식의 새 이미지 태그입니다. 아래 표시된 것처럼 단일 태그를 설정하거나 목록에서 여러 태그를 지정할 수 있습니다.
* `push`: `true`로 설정하면 이미지가 성공적으로 빌드되었을 경우 레지스트리에 푸시됩니다.

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

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

name: Publish Docker image

on:
  release:
    types: [published]

jobs:
  push_to_registry:
    name: Push Docker image to Docker Hub
    runs-on: [self-hosted]
    permissions:
      packages: write
      contents: read
      
      
    steps:
      - name: Check out the repo
        uses: actions/checkout@v6

      - 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 }}

```

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

## 에 이미지 게시 GitHub Packages

> \[!NOTE] Container registry는 현재 공개 미리 보기의 GitHub Enterprise Server 버전이며 변경될 수 있습니다.

GitHub Packages 및 하위 도메인 격리를 모두 사용하도록 설정해야 Container registry를 사용할 수 있습니다. 자세한 내용은 [컨테이너 레지스트리 작업](/ko/enterprise-server@3.22/packages/working-with-a-github-packages-registry/working-with-the-container-registry)을(를) 참조하세요.

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

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

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

* `registry`: 로 설정`containers.HOSTNAME`해야 합니다.
* `username`: 컨텍스트를 `${{ github.actor }}` 사용하여 워크플로 실행을 트리거한 사용자의 사용자 이름을 자동으로 사용할 수 있습니다. 자세한 내용은 [문맥 참조](/ko/enterprise-server@3.22/actions/reference/workflows-and-actions/contexts#github-context)을(를) 참조하세요.
* `password`: 자동으로 생성된 `GITHUB_TOKEN` 비밀을 암호에 사용할 수 있습니다. 자세한 내용은 [워크플로에서 인증에 GITHUB\_TOKEN 사용](/ko/enterprise-server@3.22/actions/tutorials/authenticate-with-github_token)을(를) 참조하세요.

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

* `push`: 설정 `true`하면 이미지가 성공적으로 빌드된 경우 레지스트리에 푸시됩니다.
* `tags`: 형식 `containers.HOSTNAME/OWNER/REPOSITORY/IMAGE_NAME:VERSION`으로 설정해야 합니다.

  예를 들어, `octo-image`에 저장된 GitHub Enterprise Server 이미지가 `https://HOSTNAME/octo-org/octo-repo`에서 `tags` 옵션을 `containers.HOSTNAME/octo-org/octo-repo/octo-image:latest`로 설정해야 합니다. 아래와 같이 단일 태그를 설정하거나 목록에 여러 태그를 지정할 수 있습니다.

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

```yaml annotate copy
#
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: containers.HOSTNAME
  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: [self-hosted]
    # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
    permissions:
      contents: read
      packages: write
      
      
      #
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
      # 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 }}
      
```

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

## Docker Hub 및 GitHub Packages 이미지 게시

> \[!NOTE] Container registry는 현재 공개 미리 보기의 GitHub Enterprise Server 버전이며 변경될 수 있습니다.

GitHub Packages 및 하위 도메인 격리를 모두 사용하도록 설정해야 Container registry를 사용할 수 있습니다. 자세한 내용은 [컨테이너 레지스트리 작업](/ko/enterprise-server@3.22/packages/working-with-a-github-packages-registry/working-with-the-container-registry)을(를) 참조하세요.

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

다음 예제 워크플로는 이전 섹션의 단계(<c0>Docker Hub\</c0에 이미지 게시> 및 <c2><c1 /></c2>에 이미지 게시)를 사용하여 두 레지스트리에 푸시하는 단일 워크플로를 만듭니다.

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

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

name: Publish Docker image

on:
  release:
    types: [published]

jobs:
  push_to_registries:
    name: Push Docker image to multiple registries
    runs-on: [self-hosted]
    permissions:
      packages: write
      contents: read
    steps:
      - name: Check out the repo
        uses: actions/checkout@v6

      - 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: containers.HOSTNAME
          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
            containers.HOSTNAME/${{ 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 }}
```

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

## 실습

Docker 이미지 게시 연습을 사용하여 [Docker 이미지를](https://github.com/skills/publish-docker-images)GitHub Skills 게시하는 방법을 연습합니다.

이 연습에서는 다음 방법을 알아봅니다.

* GitHub Packages에 `GITHUB_TOKEN`을(를) 사용하여 인증합니다.
* Container registry (`ghcr.io`)에 컨테이너 이미지를 빌드하고 게시합니다.
* 공식 Docker 작업(예: `docker/login-action`, `docker/build-push-action`및 `docker/setup-buildx-action`.)을 사용합니다.
* 분기, 끌어오기 요청 및 릴리스를 기반으로 `docker/metadata-action` 태그를 자동으로 생성합니다.
* 적절한 컨테이너 버전 관리로 기능, 끌어오기 요청 및 릴리스를 만듭니다.