Skip to main content

Publishing Docker images

In this tutorial, you'll learn how to publish Docker images to a registry, such as Docker Hub or GitHub Packages, as part of your continuous integration (CI) workflow.

Introduction

This guide shows you how to create a workflow that performs a Docker build, and then publishes Docker images to Docker Hub or GitHub Packages. With a single workflow, you can publish images to a single registry or to multiple registries.

참고 항목

If you want to push to another third-party Docker registry, the example in the Publishing images to GitHub Packages section can serve as a good template.

Prerequisites

We recommend that you have a basic understanding of workflow configuration options and how to create a workflow file. For more information, see 워크플로 작성.

You might also find it helpful to have a basic understanding of the following:

About image configuration

This guide assumes that you have a complete definition for a Docker image stored in a GitHub repository. For example, your repository must contain a Dockerfile, and any other files needed to perform a Docker build to create an image.

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

In this guide, we will use the Docker build-push-action action to build the Docker image and push it to one or more Docker registries. For more information, see build-push-action.

참고 항목

GitHub Enterprise Server의 GitHub Actions는 GitHub.com 또는 GitHub Marketplace의 작업에 대한 액세스가 제한될 수 있습니다. 자세한 내용은 GitHub.com의 작업에 대한 액세스 관리을(를) 참조하고 GitHub Enterprise 사이트 관리자에게 문의하세요.

Publishing images to Docker Hub

참고 항목

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

Each time you create a new release on GitHub, you can trigger a workflow to publish your image. The workflow in the example below runs when the release event triggers with the published activity type.

In the example workflow below, we use the Docker login-action and build-push-action actions to build the Docker image and, if the build succeeds, push the built image to Docker Hub.

To push to Docker Hub, you will need to have a Docker Hub account, and have a Docker Hub repository created. For more information, see Pushing a Docker container image to Docker Hub in the Docker documentation.

The login-action options required for Docker Hub are:

  • username and password: This is your Docker Hub username and password. We recommend storing your Docker Hub username and password as secrets so they aren't exposed in your workflow file. For more information, see Using secrets in GitHub Actions.

The metadata-action option required for Docker Hub is:

  • images: The namespace and name for the Docker image you are building/pushing to Docker Hub.

The build-push-action options required for Docker Hub are:

  • tags: The tag of your new image in the format DOCKER-HUB-NAMESPACE/DOCKER-HUB-REPOSITORY:VERSION. You can set a single tag as shown below, or specify multiple tags in a list.
  • push: If set to true, the image will be pushed to the registry if it is built successfully.
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: [self-hosted]
    permissions:
      packages: write
      contents: read
      
      
    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 }}

The above workflow checks out the GitHub repository, uses the login-action to log in to the registry, and then uses the build-push-action action to: build a Docker image based on your repository's Dockerfile; push the image to Docker Hub, and apply a tag to the image.

Publishing images to GitHub Packages

참고 항목

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

GitHub Packages 및 하위 도메인 격리를 모두 사용하도록 설정해야 Container registry를 사용할 수 있습니다. 자세한 내용은 컨테이너 레지스트리 작업을(를) 참조하세요.

Each time you create a new release on GitHub, you can trigger a workflow to publish your image. The workflow in the example below runs when a change is pushed to the release branch.

In the example workflow below, we use the Docker login-action and build-push-action actions to build the Docker image, and if the build succeeds, push the built image to GitHub Packages.

The login-action options required for GitHub Packages are:

  • registry: Must be set to containers.HOSTNAME.
  • username: You can use the ${{ github.actor }} context to automatically use the username of the user that triggered the workflow run. For more information, see Contexts reference.
  • password: You can use the automatically-generated GITHUB_TOKEN secret for the password. For more information, see Use GITHUB_TOKEN in workflows.

The build-push-action options required for GitHub Packages are:

  • push: If set to true, the image will be pushed to the registry if it is built successfully.

  • tags: Must be set in the format containers.HOSTNAME/OWNER/REPOSITORY/IMAGE_NAME:VERSION.

    For example, for an image named octo-image stored on GitHub Enterprise Server at https://HOSTNAME/octo-org/octo-repo, the tags option should be set to containers.HOSTNAME/octo-org/octo-repo/octo-image:latest . You can set a single tag as shown below, or specify multiple tags in a list.

참고 항목

  • 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: containers.HOSTNAME
  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: [self-hosted]

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

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

The above workflow is triggered by a push to the "release" branch. It checks out the GitHub repository, and uses the login-action to log in to the Container registry. It then extracts labels and tags for the Docker image. Finally, it uses the build-push-action action to build the image and publish it on the Container registry.

Publishing images to Docker Hub and GitHub Packages

참고 항목

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

GitHub Packages 및 하위 도메인 격리를 모두 사용하도록 설정해야 Container registry를 사용할 수 있습니다. 자세한 내용은 컨테이너 레지스트리 작업을(를) 참조하세요.

In a single workflow, you can publish your Docker image to multiple registries by using the login-action and build-push-action actions for each registry.

The following example workflow uses the steps from the previous sections (Publishing images to Docker Hub and Publishing images to GitHub Packages) to create a single workflow that pushes to both registries.

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: [self-hosted]
    permissions:
      packages: write
      contents: read
      
      
    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: 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 }}

The above workflow checks out the GitHub repository, uses the login-action twice to log in to both registries and generates tags and labels with the metadata-action action. Then the build-push-action action builds and pushes the Docker image to Docker Hub and the Container registry.