{"meta":{"title":"使用容器注册表","intro":"可以在 . Container registry. 中存储和管理 Docker 和 OCI 映像。","product":"GitHub Packages","breadcrumbs":[{"href":"/zh/packages","title":"GitHub Packages"},{"href":"/zh/packages/working-with-a-github-packages-registry","title":"使用 GitHub Packages 注册表"},{"href":"/zh/packages/working-with-a-github-packages-registry/working-with-the-container-registry","title":"容器注册表"}],"documentType":"article"},"body":"# 使用容器注册表\n\n可以在 . Container registry. 中存储和管理 Docker 和 OCI 映像。\n\n## 关于 Container registry\n\nContainer registry 将容器映像存储在组织或个人帐户中，并允许你将映像与存储库相关联。 可以选择是从存储库继承权限，还是独立于存储库设置精细权限。 你也可以匿名访问公共容器映像。\n\n## 关于Container registry的支持\n\nContainer registry当前支持以下容器映像格式：\n\n* [Docker 映像清单 V2，架构 2](https://docs.docker.com/registry/spec/manifest-v2-2/)\n* [开放容器计划 (OCI) 规范](https://github.com/opencontainers/image-spec)\n\n安装或发布 Docker 映像时，Container registry支持外来层，例如 Windows 映像。\n\n## 对 Container registry 进行身份验证\n\n> \\[!NOTE]\n> GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息，请参阅“[管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)”。\n\n需要访问令牌才能发布、安装和删除专用、内部和公共包。\n\n你可以使用 personal access token (classic) 向 GitHub Packages 或 GitHub API 进行身份验证。 创建 personal access token (classic) 时，可根据需要为令牌分配不同的作用域。 有关 personal access token (classic) 的包相关作用域的详细信息，请参阅 [关于 GitHub Packages 的权限](/zh/packages/learn-github-packages/about-permissions-for-github-packages#about-scopes-and-permissions-for-package-registries)。\n\n要在 GitHub Packages 工作流程内向 GitHub Actions 注册表验证，您可以使用：\n\n* `GITHUB_TOKEN` 发布与工作流存储库相关联的包。\n* 范围至少为 `read:packages` 的 personal access token (classic)，用于安装与其他专用存储库关联的包（如果向存储库授予对包的读取访问权限，可以使用 `GITHUB_TOKEN`。 请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)）。\n\n### 在 GitHub Actions 工作流中进行身份验证\n\n此注册表支持精细权限。 对于支持细粒度权限的注册表，如果您的GitHub Actions工作流使用personal access token向注册表进行身份验证，我们强烈建议您更新工作流以使用`GITHUB_TOKEN`。 有关更新通过 personal access token 向注册表进行身份验证的工作流的指导，请参阅 [使用 GitHub Actions 发布和安装包](/zh/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-a-registry-using-a-personal-access-token)。\n\n> \\[!NOTE]\n> GitHub Actions 工作流使用 REST API 删除和还原包的功能目前为 公开预览，可能随时更改。\n\n如果令牌对该包具有 `GITHUB_TOKEN` 权限，则可以在 GitHub Actions 工作流中使用 `admin` 通过 REST API 删除或恢复软件包。 通过工作流发布软件包的仓库，以及你已明确关联到软件包的仓库，会自动获得对该仓库中软件包的 `admin` 权限。\n\n有关 `GITHUB_TOKEN` 的详细信息，请参阅 [在工作流中使用 GITHUB\\_TOKEN 进行身份验证](/zh/actions/tutorials/authenticate-with-github_token#using-the-github_token-in-a-workflow)。 有关在操作中使用注册表时的最佳做法的详细信息，请参阅 [被入侵的运行器](/zh/actions/concepts/security/compromised-runners#cross-repository-access)。\n\n您还可以选择针对GitHub Codespaces和GitHub Actions分别为包授予访问权限。 有关详细信息，请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-github-codespaces-access-to-your-package) 和 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-workflow-access-to-your-package)。\n\n### 使用personal access token (classic)进行身份验证\n\n> \\[!NOTE]\n> GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息，请参阅“[管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)”。\n\n1. 创建一个新的 personal access token (classic)，并为其设置适合您要完成的任务的范围。 如果您的组织需要 SSO，则必须为新令牌启用 SSO。\n\n   > \\[!NOTE]\n   > 默认情况下，当您在用户界面中为 `write:packages` 选择 personal access token (classic) 范围时，系统也会同时选中 `repo` 范围。\n   > `repo` 权限范围授予了不必要且过于宽泛的访问权限，我们特别建议你避免将其用于 GitHub Actions 工作流。 有关详细信息，请参阅“[被入侵的运行器](/zh/actions/concepts/security/compromised-runners#cross-repository-access)”。 作为一种变通方法，你可以通过以下 URL 在用户界面中仅为你的 `write:packages` 选择 personal access token (classic) 作用域：`https://github.com/settings/tokens/new?scopes=write:packages`\n\n   * 选择 `read:packages` 范围以下载容器映像并读取其元数据。\n   * 选择 `write:packages` 范围以下载和上传容器映像并读写其元数据。\n   * 选择 `delete:packages` 范围以删除容器映像。\n\n   有关详细信息，请参阅“[管理个人访问令牌](/zh/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)”。\n\n2. 保存你的 personal access token (classic)。 建议将令牌保存为环境变量。\n\n   ```shell\n   export CR_PAT=YOUR_TOKEN\n   ```\n\n3. 使用适用于您的容器类型的 CLI，登录到位于 Container registry 的 `ghcr.io` 服务。\n\n   ```shell\n   $ echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin\n   > Login Succeeded\n   ```\n\n## 推送容器映像\n\n此示例推送最新版本的 `IMAGE_NAME`。\n\n```shell\ndocker push ghcr.io/NAMESPACE/IMAGE_NAME:latest\n```\n\n将 `NAMESPACE` 替换为你希望作为映像限定范围的个人帐户或组织的名称。\n\n此示例推送映像的 `2.5` 版本。\n\n```shell\ndocker push ghcr.io/NAMESPACE/IMAGE_NAME:2.5\n```\n\n首次发布包时，默认可见性是私有的。 若要更改可见性或设置访问权限，请参阅 [配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)。 可以使用用户界面或命令行将已发布的包链接到存储库。 有关详细信息，请参阅“[将仓库连接到软件包](/zh/packages/learn-github-packages/connecting-a-repository-to-a-package)”。\n\n从命令行推送容器映像时，默认情况下，该映像不会链接到存储库。 即使使用与存储库名称匹配的命名空间（例如 `ghcr.io/octocat/my-repo:latest`）标记映像，也是如此。\n\n将存储库连接到容器包的最简单方法是使用 `${{secrets.GITHUB_TOKEN}}` 从工作流发布包，因为包含工作流的存储库会自动链接。 请注意，如果之前已将包推送到同一命名空间，但尚未将包连接到存储库，则 `GITHUB_TOKEN` 将无权推送包。\n\n要在使用命令行发布镜像时连接存储库，并确保你的 `GITHUB_TOKEN` 在使用 GitHub Actions 工作流时具有适当的权限，建议将标签 `org.opencontainers.image.source` 添加到 `Dockerfile`。 有关详细信息，请参阅本文中的“[标记容器映像](#labelling-container-images)”和“[使用 GitHub Actions 发布和安装包](/zh/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions)”。\n\n## 拉取容器映像\n\n### 通过摘要拉取\n\n为确保始终使用相同的映像，可以通过 `digest` SHA 值指定要拉取的确切容器映像版本。\n\n1. 若要查找摘要 SHA 值，请使用 `docker inspect` 或 `docker pull` 并在 `Digest:` 之后复制 SHA 值\n\n   ```shell\n   docker inspect ghcr.io/NAMESPACE/IMAGE_NAME\n   ```\n\n   将 `NAMESPACE` 替换为要作为映像限定范围的个人帐户或组织的名称。\n\n2. 按需要在本地删除映像。\n\n   ```shell\n   docker rmi ghcr.io/NAMESPACE/IMAGE_NAME:latest\n   ```\n\n3. 在映像名称后添加 `@YOUR_SHA_VALUE` 以拉取容器映像。\n\n   ```shell\n   docker pull ghcr.io/NAMESPACE/IMAGE_NAME@sha256:82jf9a84u29hiasldj289498uhois8498hjs29hkuhs\n   ```\n\n### 按名称拉取\n\n```shell\ndocker pull ghcr.io/NAMESPACE/IMAGE_NAME\n```\n\n将 `NAMESPACE` 替换为要作为映像限定范围的个人帐户或组织的名称。\n\n### 按名称和版本拉取\n\n显示按名称和 `1.14.1` 版本标记拉取的映像的 Docker CLI 示例：\n\n```shell\n$ docker pull ghcr.io/NAMESPACE/IMAGE_NAME:1.14.1\n> 5e35bd43cf78: Pull complete\n> 0c48c2209aab: Pull complete\n> fd45dd1aad5a: Pull complete\n> db6eb50c2d36: Pull complete\n> Digest: sha256:ae3b135f133155b3824d8b1f62959ff8a72e9cf9e884d88db7895d8544010d8e\n> Status: Downloaded newer image for ghcr.io/NAMESPACE/IMAGE_NAME/release:1.14.1\n> ghcr.io/NAMESPACE/IMAGE_NAME/release:1.14.1\n```\n\n将 `NAMESPACE` 替换为要作为映像限定范围的个人帐户或组织的名称。\n\n### 按名称和最新版本拉取\n\n```shell\n$ docker pull ghcr.io/NAMESPACE/IMAGE_NAME:latest\n> latest: Pulling from NAMESPACE/IMAGE_NAME\n> Digest: sha256:b3d3e366b55f9a54599220198b3db5da8f53592acbbb7dc7e4e9878762fc5344\n> Status: Downloaded newer image for ghcr.io/NAMESPACE/IMAGE_NAME:latest\n> ghcr.io/NAMESPACE/IMAGE_NAME:latest\n```\n\n将 `NAMESPACE` 替换为要作为映像限定范围的个人帐户或组织的名称。\n\n## 构建容器镜像\n\n此示例生成 `hello_docker` 映像：\n\n```shell\ndocker build -t hello_docker .\n```\n\n## 给容器镜像打标签\n\n1. 找到要标记的 Docker 映像的 ID。\n\n   ```shell\n   $ docker images\n   > REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE\n   > ghcr.io/my-org/hello_docker         latest            38f737a91f39        47 hours ago        91.7MB\n   > hello-world                                           latest              fce289e99eb9        16 months ago       1.84kB\n   ```\n\n2. 使用映像 ID 以及所需的映像名称和托管目标标记 Docker 映像。\n\n   ```shell\n   docker tag 38f737a91f39 ghcr.io/NAMESPACE/NEW_IMAGE_NAME:latest\n   ```\n\n将 `NAMESPACE` 替换为你希望作为映像限定范围的个人帐户或组织的名称。\n\n## 标记容器映像\n\n可以使用预定义的注释键向容器映像添加元数据，包括说明、许可证和源存储库。 受支持的键的值将显示在该镜像的软件包页面上。\n\n对于大多数映像，可以使用 Docker 标签将注释密钥添加到映像。 有关详细信息，请参阅 Docker 官方文档中的“[LABEL](https://docs.docker.com/engine/reference/builder/#label)”和 [](https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys) 存储库中的“`opencontainers/image-spec`”。\n\n对于多架构映像，可以通过将适当的注释密钥添加到映像清单中的 `annotations` 字段来为映像添加说明。 有关详细信息，请参阅[向多架构映像添加说明](#adding-a-description-to-multi-arch-images)。\n\nContainer registry 中支持以下注释键。\n\n| 密钥                                     | 说明                                                                                                                                                                                   |\n| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `org.opencontainers.image.source`      | 与包关联的存储库的 URL。 有关详细信息，请参阅“[将仓库连接到软件包](/zh/packages/learn-github-packages/connecting-a-repository-to-a-package#connecting-a-repository-to-a-container-image-using-the-command-line)”。 |\n| `org.opencontainers.image.description` | 纯文本说明，限制在 512 个字符以内。 此说明将显示在包页中的包名称下方。                                                                                                                                               |\n| `org.opencontainers.image.licenses`    | SPDX 许可证标识符，如“MIT”，限制在 256 个字符以内。 许可证将显示在包页的“详细信息”边栏中。 有关详细信息，请参阅 [SPDX 许可证列表](https://spdx.org/licenses/)。                                                                          |\n\n若要添加密钥作为 Docker 标签，建议在 `LABEL` 中使用 `Dockerfile` 指令。 例如，如果你是用户 `octocat`，拥有 `my-repo`，并且映像是根据 MIT 许可证的条款分发的，可以在 `Dockerfile` 中添加以下行：\n\n```dockerfile\nLABEL org.opencontainers.image.source=https://github.com/octocat/my-repo\nLABEL org.opencontainers.image.description=\"My container image\"\nLABEL org.opencontainers.image.licenses=MIT\n```\n\n> \\[!NOTE]\n> 如果发布链接到存储库的包，该包会自动继承链接存储库的访问权限，链接存储库中的 GitHub Actions 工作流会自动获得对包的访问权限，除非你的组织已禁用访问权限的自动继承。 有关详细信息，请参阅“[配置包的访问控制和可见性](/zh/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#about-inheritance-of-access-permissions)”。\n\n或者，可以使用 `docker build` 命令在生成时向映像添加标签。\n\n```shell\n$ docker build \\\n --label \"org.opencontainers.image.source=https://github.com/octocat/my-repo\" \\\n --label \"org.opencontainers.image.description=My container image\" \\\n --label \"org.opencontainers.image.licenses=MIT\"\n```\n\n### 向多架构映像添加说明\n\n多架构映像是支持多种体系结构的映像。 它的原理是在单一清单中引用一系列映像，其中每个映像都支持不同的体系结构。\n\n多架构映像的“包”页面中的说明是从映像清单中的 `annotations` 字段获取的。 与 Docker 标签一样，注释提供了一种将元数据与映像相关联的方法，并支持预定义的注释密钥。 有关详细信息，请参阅 [注释](https://github.com/opencontainers/image-spec/blob/main/annotations.md) 在 `opencontainers/image-spec` 存储库中。\n\n若要为多架构映像提供说明，请在清单的 `org.opencontainers.image.description` 字段中为 `annotations` 键设置一个值，如下所示。\n\n```json\n\"annotations\": {\n  \"org.opencontainers.image.description\": \"My multi-arch image\"\n}\n```\n\n例如，以下 GitHub Actions 工作流步骤构建并推送多架构镜像。\n`outputs` 参数设置图像的描述。\n\n```yaml\n# 此工作流使用未经 GitHub 认证的操作。\n# 它们由第三方提供，并受\n# 单独的服务条款、隐私政策和支持\n# 文档。\n\n- name: Build and push Docker image\n  uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4\n  with:\n    context: .\n    file: ./Dockerfile\n    platforms: ${{ matrix.platforms }}\n    push: true\n    outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=My multi-arch image\n```\n\n## 故障排除\n\n* Container registry每个层的大小限制为 10 GB。\n* Container registry 的上传超时限制为 10 分钟。"}