Docker 이미지 게시하기
Docker 이미지 게시하기
이 튜토리얼에서는 지속적 통합(CI) 워크플로우의 일부로 Docker 이미지를 Docker Hub나 GitHub Packages 같은 레지스트리에 게시하는 방법을 알려드릴게요.
출처: 문서
본문
Introduction
이 가이드는 Docker 빌드를 수행한 다음 Docker 이미지를 Docker Hub 또는 GitHub Packages에 게시하는 워크플로우를 만드는 방법을 보여줍니다. 단일 워크플로우로 하나의 레지스트리 또는 여러 레지스트리에 이미지를 게시할 수 있어요.
[!NOTE] 다른 제3자 Docker 레지스트리에 푸시하려면 Publishing images to GitHub Packages 섹션의 예시가 좋은 템플릿이 될 수 있어요.
Prerequisites
워크플로우 구성 옵션과 워크플로우 파일을 만드는 방법에 대한 기본적인 이해가 있으면 좋아요. 자세한 내용은 Writing workflows 문서를 참고하세요.
다음에 대한 기본적인 이해가 있으면 더 도움이 될 수 있어요.
- Using secrets in GitHub Actions
- Use GITHUB_TOKEN for authentication in workflows
- Working with the Container registry
About image configuration
이 가이드는 GitHub 저장소에 저장된 Docker 이미지에 대한 완전한 정의가 있다고 가정해요. 예를 들어 저장소에는 Dockerfile과, 이미지를 만들기 위한 Docker 빌드를 수행하는 데 필요한 다른 파일이 포함되어 있어야 해요.
사전 정의된 주석 키(annotation keys)를 사용해서 설명, 라이선스, 소스 저장소를 포함한 메타데이터를 컨테이너 이미지에 추가할 수 있어요. 자세한 내용은 Working with the Container registry 문서를 참고하세요.
이 가이드에서는 Docker build-push-action 액션을 사용해서 Docker 이미지를 빌드하고 하나 이상의 Docker 레지스트리로 푸시할 거예요. 자세한 내용은 build-push-action을 참고하세요.
Publishing images to Docker Hub
[!NOTE] Docker Hub는 일반적으로 push 및 pull 작업 모두에 속도 제한을 적용하며, 이는 자체 호스팅 러너의 job에 영향을 줄 거예요. 그러나 GitHub 호스팅 러너는 GitHub와 Docker 간의 계약에 따라 이러한 제한의 대상이 아니에요.
GitHub에서 새 릴리스를 만들 때마다 이미지를 게시하도록 워크플로우를 트리거할 수 있어요. 아래 예시의 워크플로우는 release 이벤트가 published 활동 유형으로 트리거될 때 실행돼요.
아래 예시 워크플로우에서는 Docker login-action과 build-push-action 액션을 사용해서 Docker 이미지를 빌드하고, 빌드가 성공하면 빌드된 이미지를 Docker Hub로 푸시해요.
Docker Hub로 푸시하려면 Docker Hub 계정이 있어야 하고 Docker Hub 저장소를 만들어야 해요. 자세한 내용은 Docker 문서의 Pushing a Docker container image to Docker Hub를 참고하세요.
Docker Hub에 필요한 login-action 옵션:
username및password: Docker Hub 사용자 이름과 비밀번호예요. 워크플로우 파일에 노출되지 않도록 Docker Hub 사용자 이름과 비밀번호를 secret으로 저장하는 것이 좋아요. 자세한 내용은 Using secrets in 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로 설정하면 이미지가 성공적으로 빌드되면 레지스트리로 푸시돼요.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
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@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 }}
- name: Generate artifact attestation
uses: actions/attest@v4
with:
subject-name: index.docker.io/my-docker-hub-namespace/my-docker-hub-repository
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
위 워크플로우는 GitHub 저장소를 체크아웃하고, login-action을 사용해서 레지스트리에 로그인한 다음 build-push-action 액션을 사용해서: 저장소의 Dockerfile에 기반한 Docker 이미지를 빌드하고; 이미지를 Docker Hub로 푸시하고; 이미지에 태그를 적용해요.
마지막 단계에서는 이미지에 대한 아티팩트 증언(artifact attestation)을 생성해서 공급망 보안을 강화해요. 자세한 내용은 Using artifact attestations to establish provenance for builds 문서를 참고하세요.
Publishing images to GitHub Packages
GitHub에서 새 릴리스를 만들 때마다 이미지를 게시하도록 워크플로우를 트리거할 수 있어요. 아래 예시의 워크플로우는 release 브랜치에 변경 사항이 푸시될 때 실행돼요.
아래 예시 워크플로우에서는 Docker login-action, metadata-action, build-push-action 액션을 사용해서 Docker 이미지를 빌드하고, 빌드가 성공하면 빌드된 이미지를 GitHub Packages로 푸시해요.
GitHub Packages에 필요한 login-action 옵션:
registry:ghcr.io로 설정해야 해요.username:${{ github.actor }}컨텍스트를 사용해서 워크플로우 실행을 트리거한 사용자의 사용자 이름을 자동으로 사용할 수 있어요. 자세한 내용은 Contexts reference 문서를 참고하세요.password: 비밀번호에 자동 생성된GITHUB_TOKENsecret을 사용할 수 있어요. 자세한 내용은 Use GITHUB_TOKEN for authentication in workflows 문서를 참고하세요.
GitHub Packages에 필요한 metadata-action 옵션:
images: 빌드하는 Docker 이미지의 네임스페이스와 이름.
GitHub Packages에 필요한 build-push-action 옵션:
context: 지정된 경로에 있는 파일 집합으로 빌드의 컨텍스트를 정의해요.push:true로 설정하면 이미지가 성공적으로 빌드되면 레지스트리로 푸시돼요.tags및labels:metadata-action의 출력으로 채워져요.
[!NOTE]
- 이 워크플로우는 GitHub가 인증하지 않은 액션을 사용해요. 제3자가 제공하며 별도의 서비스 약관, 개인정보 보호정책, 지원 문서가 적용돼요.
- GitHub는 액션을 커밋 SHA에 고정하는 것을 권장해요. 더 새로운 버전을 얻으려면 SHA를 업데이트해야 해요. 태그나 브랜치를 참조할 수도 있지만, 액션은 경고 없이 변경될 수 있어요.
#
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@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 }}
# 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 [Using artifact attestations to establish provenance for builds](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds).
- name: Generate artifact attestation
uses: actions/attest@v4
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
위 워크플로우는 "release" 브랜치에 대한 push로 트리거돼요. GitHub 저장소를 체크아웃하고 login-action을 사용해서 Container registry에 로그인해요. 그런 다음 Docker 이미지에 대한 레이블과 태그를 추출해요. 마지막으로 build-push-action 액션을 사용해서 이미지를 빌드하고 Container registry에 게시해요.
Publishing images to Docker Hub and GitHub Packages
단일 워크플로우에서 각 레지스트리에 login-action과 build-push-action 액션을 사용해서 Docker 이미지를 여러 레지스트리에 게시할 수 있어요.
다음 예시 워크플로우는 이전 섹션(Publishing images to Docker Hub 및 Publishing images to GitHub Packages)의 단계를 사용해서 두 레지스트리 모두로 푸시하는 단일 워크플로우를 만들어요.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
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
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: 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 }}
위 워크플로우는 GitHub 저장소를 체크아웃하고, login-action을 두 번 사용해서 두 레지스트리에 로그인하고, metadata-action 액션으로 태그와 레이블을 생성해요.
그런 다음 build-push-action 액션이 Docker 이미지를 빌드하고 Docker Hub와 Container registry로 푸시해요.
[!NOTE] 여러 레지스트리로 푸시할 때:
- 이미지 다이제스트(digest)가 레지스트리마다 달라져서 증언 검증이 어려워질 수 있어요.
- 일관된 다이제스트를 유지하고 단일 증언이 모든 복사본을 검증하도록 하려면 먼저 하나의 레지스트리로 푸시하고
crane copy같은 도구를 사용해서 이미지를 다른 곳에 복제하세요.- 대신 각 레지스트리에 별도로 빌드하고 푸시하기로 선택했다면, 아티팩트가 검증 가능한 상태를 유지하도록 각각에 대해 고유한 증언을 생성해야 해요.
Hands-on practice
Publishing Docker images GitHub Skills 연습으로 Docker 이미지 게시를 연습해 보세요.
이 연습에서는 다음을 배울 수 있어요.
GITHUB_TOKEN을 사용해서 GitHub Packages에 인증하기.- 컨테이너 이미지를 Container registry(
ghcr.io)에 빌드하고 게시하기. docker/login-action,docker/build-push-action,docker/setup-buildx-action같은 공식 Docker 액션 사용하기.docker/metadata-action으로 브랜치, 풀 리퀘스트, 릴리스에 따라 태그를 자동 생성하기.- 적절한 컨테이너 버전 관리를 갖춘 기능, 풀 리퀘스트, 릴리스 만들기.