{"meta":{"title":"发布 Docker 映像","intro":"本教程介绍如何将 Docker 映像发布到注册表，例如Docker Hub或 GitHub Packages，作为持续集成（CI）工作流的一部分。","product":"GitHub Actions","breadcrumbs":[{"href":"/zh/enterprise-server@3.17/actions","title":"GitHub Actions"},{"href":"/zh/enterprise-server@3.17/actions/tutorials","title":"教程"},{"href":"/zh/enterprise-server@3.17/actions/tutorials/publish-packages","title":"发布软件包"},{"href":"/zh/enterprise-server@3.17/actions/tutorials/publish-packages/publish-docker-images","title":"发布 Docker 映像"}],"documentType":"article"},"body":"# 发布 Docker 映像\n\n本教程介绍如何将 Docker 映像发布到注册表，例如Docker Hub或 GitHub Packages，作为持续集成（CI）工作流的一部分。\n\n## 简介\n\n本指南介绍如何创建执行 Docker 生成的工作流，然后将 Docker 映像发布到 Docker Hub 或 GitHub Packages。 通过单个工作流程，您可以将映像发布到单一注册表或多个注册表。\n\n> \\[!NOTE]\n> 如果要推送到另一个第三方 Docker 注册表，[发布映像到 GitHub Packages](#publishing-images-to-github-packages) 部分中的示例可以用作很好的模板。\n\n## 先决条件\n\n建议基本了解工作流程配置选项和如何创建工作流程文件。 有关详细信息，请参阅“[撰写工作流程](/zh/enterprise-server@3.17/actions/how-tos/write-workflows)”。\n\n您可能还发现基本了解以下内容是有帮助的：\n\n* [在 GitHub Actions 中使用机密](/zh/enterprise-server@3.17/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)\n* [在工作流中使用 GITHUB\\_TOKEN 进行身份验证](/zh/enterprise-server@3.17/actions/tutorials/authenticate-with-github_token)\n* [使用 Docker 注册表](/zh/enterprise-server@3.17/packages/working-with-a-github-packages-registry/working-with-the-docker-registry)\n\n## 关于映像配置\n\n本指南假定你对存储库中 GitHub 存储的 Docker 映像有完整的定义。 例如，存储库必须包含一个 Dockerfile，以及执行 Docker 构建以创建映像所需的任何其他文件。\n\n可以使用预定义的注释键向容器映像添加元数据，包括说明、许可证和源存储库。 有关详细信息，请参阅 [使用容器注册表](/zh/enterprise-server@3.17/packages/working-with-a-github-packages-registry/working-with-the-container-registry#labelling-container-images)。\n\n在本指南中，我们将使用 Docker `build-push-action` 操作来构建 Docker 映像并将其推送到一个或多个 Docker 注册表。 有关详细信息，请参阅 [`build-push-action`](https://github.com/marketplace/actions/build-and-push-docker-images)。\n\n> \\[!NOTE]\n> 在 GitHub Actions 上的 GitHub Enterprise Server 可能对 GitHub.com 或 GitHub Marketplace 上的操作具有有限的访问权限。 有关详细信息，请参阅 [从 GitHub.com 管理对操作的访问](/zh/enterprise-server@3.17/admin/managing-github-actions-for-your-enterprise/managing-access-to-actions-from-githubcom) 并联系 GitHub Enterprise 站点管理员。\n\n## 将映像发布到Docker Hub\n\n> \\[!NOTE]\n> Docker Hub 通常会对推送和拉取操作设置速率限制，这将影响自托管运行程序上的作业。 不过，根据 GitHub 和 Docker 之间的协议，GitHub 托管的运行程序不受这些限制的约束。\n\n每次在GitHub上创建新版本发布时，都可以触发工作流来发布镜像。 以下示例中的工作流在 `release` 事件以 `published` 活动类型触发时运行。\n\n在下面的示例工作流中，我们使用 Docker `login-action` 和 `build-push-action` 操作生成 Docker 映像，如果生成成功，请将生成的映像推送到Docker Hub。\n\n若要推送到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)。\n\nDocker Hub所需的 `login-action` 选项包括：\n\n* `username` 和 `password`：这是Docker Hub用户名和密码。 建议将Docker Hub用户名和密码存储为机密，以便不会在工作流文件中公开它们。 有关详细信息，请参阅“[在 GitHub Actions 中使用机密](/zh/enterprise-server@3.17/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)”。\n\nDocker Hub所需的 `metadata-action` 选项为：\n\n* `images`：要生成/推送到Docker Hub的 Docker 映像的命名空间和名称。\n\nDocker Hub所需的 `build-push-action` 选项包括：\n\n* `tags`：你的新映像的标签，格式为 `DOCKER-HUB-NAMESPACE/DOCKER-HUB-REPOSITORY:VERSION`。 您可以如下所示设置单个标记，或在列表中指定多个标记。\n* `push`：如果设置为 `true`，则映像将推送到注册表（如果成功构建）。\n\n```yaml copy\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n# GitHub 建议将操作固定到提交 SHA。\n# 若要获取较新版本，需要更新 SHA。\n# 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\nname: Publish Docker image\n\non:\n  release:\n    types: [published]\n\njobs:\n  push_to_registry:\n    name: Push Docker image to Docker Hub\n    runs-on: [self-hosted]\n    permissions:\n      packages: write\n      contents: read\n      \n      \n    steps:\n      - name: Check out the repo\n        uses: actions/checkout@v6\n\n      - name: Log in to Docker Hub\n        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n\n      - name: Extract metadata (tags, labels) for Docker\n        id: meta\n        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7\n        with:\n          images: my-docker-hub-namespace/my-docker-hub-repository\n\n      - name: Build and push Docker image\n        id: push\n        uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671\n        with:\n          context: .\n          file: ./Dockerfile\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n\n```\n\n上述工作流检出GitHub 存储库，使用 `login-action` 登录到注册表，然后使用 `build-push-action` 动作：基于您的存储库的`Dockerfile` 构建Docker镜像；将镜像推送到 Docker Hub，并将标签应用于镜像。\n\n## 将图像发布到 GitHub Packages\n\n> \\[!NOTE] Container registry 的 公开预览 目前为GitHub Enterprise Server，可能会有改动。\n\n必须启用 GitHub Packages 和子域隔离才能使用 Container registry。 有关详细信息，请参阅“[使用容器注册表](/zh/enterprise-server@3.17/packages/working-with-a-github-packages-registry/working-with-the-container-registry)”。\n\n每次在GitHub上创建新版本发布时，都可以触发工作流来发布镜像。 以下示例中的工作流在将更改被推送到 `release` 分支时运行。\n\n在下面的示例工作流中，我们使用 Docker `login-action``build-push-action`操作生成 Docker 映像，如果生成成功，请将生成映像推送到。GitHub Packages\n\n`login-action`所需的GitHub Packages选项包括：\n\n* `registry`：必须设置为 `containers.HOSTNAME`.\n* `username`：可以使用 `${{ github.actor }}` 上下文自动使用触发工作流运行的用户的用户名。 有关详细信息，请参阅“[上下文参考](/zh/enterprise-server@3.17/actions/reference/workflows-and-actions/contexts#github-context)”。\n* `password`：可以使用自动生成 `GITHUB_TOKEN` 的密码机密。 有关详细信息，请参阅“[在工作流中使用 GITHUB\\_TOKEN 进行身份验证](/zh/enterprise-server@3.17/actions/tutorials/authenticate-with-github_token)”。\n\n`build-push-action`所需的GitHub Packages选项包括：\n\n* `push`：如果设置为 `true`，并且生成成功，则将映像推送到注册表。\n* `tags`：必须采用格式 `containers.HOSTNAME/OWNER/REPOSITORY/IMAGE_NAME:VERSION` 设置。\n\n  例如，对于一个命名为`octo-image`的映像，存储在GitHub Enterprise Server，路径为`https://HOSTNAME/octo-org/octo-repo`，该`tags`选项应设置为`containers.HOSTNAME/octo-org/octo-repo/octo-image:latest`。 可以按如下所示设置单个标记，或在列表中指定多个标记。\n\n> \\[!NOTE]\n>\n> * 此工作流使用未通过 GitHub 认证的操作。 这些操作由第三方提供，并受单独的服务条款、隐私政策和支持文档的管辖。\n> * GitHub 建议将操作固定到提交 SHA。 若要获取较新版本，需要更新 SHA。 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\n```yaml annotate copy\n#\nname: Create and publish a Docker image\n\n# Configures this workflow to run every time a change is pushed to the branch called `release`.\non:\n  push:\n    branches: ['release']\n\n# 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.\nenv:\n  REGISTRY: containers.HOSTNAME\n  IMAGE_NAME: ${{ github.repository }}\n\n# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.\njobs:\n  build-and-push-image:\n    runs-on: [self-hosted]\n    # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.\n    permissions:\n      contents: read\n      packages: write\n      \n      \n      #\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v6\n      # 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.\n      - name: Log in to the Container registry\n        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      # 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.\n      - name: Extract metadata (tags, labels) for Docker\n        id: meta\n        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7\n        with:\n          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n      # 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.\n      # 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.\n      # It uses the `tags` and `labels` parameters to tag and label the image with the output from the \"meta\" step.\n      - name: Build and push Docker image\n        id: push\n        uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4\n        with:\n          context: .\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n      \n```\n\n上述工作流程通过推送到“发行版”分支触发。 它签出GitHub存储库，并使用 `login-action` 登录到 Container registry。 然后，它将提取 Docker 映像的标签和标记。 最后，它使用 `build-push-action` 操作生成映像并将其发布到 Container registry。\n\n## 将图像发布到 Docker Hub 和 GitHub Packages\n\n> \\[!NOTE] Container registry 的 公开预览 目前为GitHub Enterprise Server，可能会有改动。\n\n必须启用 GitHub Packages 和子域隔离才能使用 Container registry。 有关详细信息，请参阅“[使用容器注册表](/zh/enterprise-server@3.17/packages/working-with-a-github-packages-registry/working-with-the-container-registry)”。\n\n在单个工作流中，你可以通过对每个注册表使用 `login-action` 和 `build-push-action` 操作将 Docker 映像发布到多个注册表。\n\n以下示例工作流使用前面各节（[发布映像到 Docker Hub](#publishing-images-to-docker-hub) 和 [将映像发布到 GitHub Packages](#publishing-images-to-github-packages)） 中的步骤来创建推送到这两个注册表的单个工作流。\n\n```yaml copy\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n# GitHub 建议将操作固定到提交 SHA。\n# 若要获取较新版本，需要更新 SHA。\n# 还可以引用标记或分支，但该操作可能会更改而不发出警告。\n\nname: Publish Docker image\n\non:\n  release:\n    types: [published]\n\njobs:\n  push_to_registries:\n    name: Push Docker image to multiple registries\n    runs-on: [self-hosted]\n    permissions:\n      packages: write\n      contents: read\n    steps:\n      - name: Check out the repo\n        uses: actions/checkout@v6\n\n      - name: Log in to Docker Hub\n        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a\n        with:\n          username: ${{ secrets.DOCKER_USERNAME }}\n          password: ${{ secrets.DOCKER_PASSWORD }}\n\n      - name: Log in to the Container registry\n        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1\n        with:\n          registry: containers.HOSTNAME\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Extract metadata (tags, labels) for Docker\n        id: meta\n        uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7\n        with:\n          images: |\n            my-docker-hub-namespace/my-docker-hub-repository\n            containers.HOSTNAME/${{ github.repository }}\n\n      - name: Build and push Docker images\n        id: push\n        uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671\n        with:\n          context: .\n          push: true\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n```\n\n上述工作流签出 GitHub 存储库，使用 `login-action` 两次登录到两个注册表，并使用 `metadata-action` 操作生成标记和标签。\n然后，`build-push-action` 操作生成 Docker 映像并将 Docker 映像推送到 Docker Hub 和 Container registry。\n\n## 动手练习\n\n练习发布 Docker 映像，使用[发布 Docker 映像](https://github.com/skills/publish-docker-images)GitHub Skills这个练习。\n\n在本练习中，你将了解如何：\n\n* 请使用 GitHub Packages 认证到 `GITHUB_TOKEN`.\n* 生成容器映像并将其发布到 Container registry （`ghcr.io`）。\n* 使用官方 Docker 操作，例如 `docker/login-action`， `docker/build-push-action`和 `docker/setup-buildx-action`。\n* 根据分支、拉取请求和发布自动生成 `docker/metadata-action` 标记。\n* 使用适当的容器版本控制创建功能、拉取请求和发布。"}