Skip to main content

使用容器注册表

You can store and manage Docker and OCI images in the Container registry.

谁可以使用此功能?

GitHub Packages 适用于 GitHub Free、GitHub Pro、面向组织的 GitHub Free、GitHub Team、GitHub Enterprise Cloud、GitHub Enterprise Server 3.0 或更高版本。
GitHub Packages 不适用于使用旧版按仓库计划的帐户所拥有的私有仓库。 此外,使用旧版按存储库计划的帐户无法访问支持精细权限的注册表,因为这些帐户按存储库计费。 Enterprise Managed Users 没有单独的存储分配来在其帐户的命名空间内发布包,但可以发布到组织的命名空间。 有关 Enterprise Managed Users 的其他信息,请参阅“关于 Enterprise Managed Users”。有关支持精细权限的注册表列表,请参阅“关于 GitHub Packages 的权限”。 有关详细信息,请参阅“GitHub 的计划”。

关于 Container registry

Container registry 将容器映像存储在组织或个人帐户中,并允许你将映像与存储库相关联。 可以选择是从存储库继承权限,还是独立于存储库设置精细权限。 你也可以匿名访问公共容器映像。

Container registry的 URL

如果在 GitHub.com 访问 GitHub,则会将包发布到 ghcr.io。 本文中的示例使用此 URL。

如果在另一个域(例如 octocorp.ghe.com)访问 GitHub,请将“ghcr.io”替换为 https://containers.SUBDOMAIN.ghe.com,其中 SUBDOMAIN 是企业的唯一子域。

关于 Container registry 支持

Container registry 目前支持以下容器映像格式:

在安装或发布 Docker 映像时,Container registry 支持外部层,如 Windows 映像。

向 Container registry 验证

GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息,请参阅“管理个人访问令牌”。

需要访问令牌才能发布、安装和删除专用、内部和公共包。

可使用 personal access token (classic) 向 GitHub Packages 或 GitHub API 进行身份验证。 创建 personal access token (classic) 时,可根据需要为令牌分配不同的作用域。 有关 personal access token (classic) 的包相关范围的详细信息,请参阅“关于 GitHub Packages 的权限”。

要在 GitHub Actions 工作流程内向 GitHub Packages 注册表验证,您可以使用:

  • GITHUB_TOKEN 发布与工作流存储库相关联的包。
  • 范围至少为 read:packages 的 personal access token (classic),用于安装与其他专用存储库(GITHUB_TOKEN 无法访问)关联的包。

在 GitHub Actions 工作流中进行身份验证

此注册表支持精细权限。 对于支持精细权限的注册表,如果 GitHub Actions 工作流使用 personal access token 向注册表进行身份验证,则强烈建议更新工作流以使用 GITHUB_TOKEN。 有关如何更新通过 personal access token 向注册表进行身份验证的工作流的指南,请参阅“使用 GitHub Actions 发布和安装包”。

**注意:**GitHub Actions 工作流使用 REST API 删除和还原包的功能目前为 公共预览版,可能随时更改。

如果令牌具有对包的 admin 权限,可以在 GitHub Actions 工作流中使用 GITHUB_TOKEN,通过 REST API 来删除或还原包。 使用工作流发布包的存储库,以及已经显式连接到包的存储库,会自动获得对存储库中包的 admin 权限。

有关 GITHUB_TOKEN 的详细信息,请参阅“自动令牌身份验证”。 有关在操作中使用注册表时的最佳做法的详细信息,请参阅“GitHub Actions 的安全强化”。

还可以选择为 GitHub Codespaces 和 GitHub Actions 单独授予对包的访问权限。 有关详细信息,请参阅“配置包的访问控制和可见性”和“配置包的访问控制和可见性”。

使用 personal access token (classic)

进行身份验证

GitHub Packages 仅支持使用 personal access token (classic) 进行身份验证。 有关详细信息,请参阅“管理个人访问令牌”。

  1. 针对要完成的任务,新创具有适当作用域的 personal access token (classic)。 如果您的组织需要 SSO,则必须为新令牌启用 SSO。

    注意:默认情况下,在用户界面中为 personal access token (classic) 选择 write:packages 作用域时,repo 作用域也将被选中。 repo 作用域提供了不必要和广泛的访问权限,我们建议你尤其避免将其用于 GitHub Actions 工作流。 有关详细信息,请参阅“GitHub Actions 的安全强化”。 解决方法是在以下 URL 的用户界面中仅为 personal access token (classic) 选择 write:packages 作用域:https://github.com/settings/tokens/new?scopes=write:packages

    • 选择 read:packages 范围以下载容器映像并读取其元数据。
    • 选择 write:packages 范围以下载和上传容器映像并读写其元数据。
    • 选择 delete:packages 范围以删除容器映像。

    有关详细信息,请参阅“管理个人访问令牌”。

  2. 保存 personal access token (classic)。 建议将令牌保存为环境变量。

    export CR_PAT=YOUR_TOKEN
    
  3. 使用容器类型的 CLI,登录到 ghcr.io 上的 Container registry 服务。

    $ echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
    > Login Succeeded
    

推送容器映像

此示例推送最新版本的 IMAGE_NAME

docker push ghcr.io/NAMESPACE/IMAGE_NAME:latest

NAMESPACE 替换为你希望作为映像限定范围的个人帐户或组织的名称。

此示例推送映像的 2.5 版本。

docker push ghcr.io/NAMESPACE/IMAGE_NAME:2.5

首次发布包时,默认可见性是私有的。 要更改可见性或设置访问权限,请参阅“配置包的访问控制和可见性”。 可以使用用户界面或命令行将已发布的包链接到存储库。 有关详细信息,请参阅“将仓库连接到包”。

从命令行推送容器映像时,默认情况下,该映像不会链接到存储库。 即使使用与存储库名称匹配的命名空间(例如 ghcr.io/octocat/my-repo:latest)标记映像,也是如此。

将存储库连接到容器包的最简单方法是使用 ${{secrets.GITHUB_TOKEN}} 从工作流发布包,因为包含工作流的存储库会自动链接。 请注意,如果之前已将包推送到同一命名空间,但尚未将包连接到存储库,则 GITHUB_TOKEN 将无权推送包。

要在从命令行发布映像时连接存储库,并确保 GITHUB_TOKEN 在使用 GitHub Actions 工作流时具有适当的权限,建议将标签 org.opencontainers.image.source 添加到 Dockerfile。 有关详细信息,请参阅本文中的“标记容器映像”和“使用 GitHub Actions 发布和安装包”。

拉取容器映像

通过摘要拉取

为确保始终使用相同的映像,可以通过 digest SHA 值指定要拉取的确切容器映像版本。

  1. 若要查找摘要 SHA 值,请使用 docker inspectdocker pull 并在 Digest: 之后复制 SHA 值

    docker inspect ghcr.io/NAMESPACE/IMAGE_NAME
    

    NAMESPACE 替换为要作为映像限定范围的个人帐户或组织的名称。

  2. 按需要在本地删除映像。

    docker rmi  ghcr.io/NAMESPACE/IMAGE_NAME:latest
    
  3. 拉取映像名称后带有 @YOUR_SHA_VALUE 的容器映像。

    docker pull ghcr.io/NAMESPACE/IMAGE_NAME@sha256:82jf9a84u29hiasldj289498uhois8498hjs29hkuhs
    

按名称拉取

docker pull ghcr.io/NAMESPACE/IMAGE_NAME

NAMESPACE 替换为要作为映像限定范围的个人帐户或组织的名称。

按名称和版本拉取

显示按名称和 1.14.1 版本标记拉取的映像的 Docker CLI 示例:

$ docker pull ghcr.io/NAMESPACE/IMAGE_NAME:1.14.1
> 5e35bd43cf78: Pull complete
> 0c48c2209aab: Pull complete
> fd45dd1aad5a: Pull complete
> db6eb50c2d36: Pull complete
> Digest: sha256:ae3b135f133155b3824d8b1f62959ff8a72e9cf9e884d88db7895d8544010d8e
> Status: Downloaded newer image for ghcr.io/NAMESPACE/IMAGE_NAME/release:1.14.1
> ghcr.io/NAMESPACE/IMAGE_NAME/release:1.14.1

NAMESPACE 替换为要作为映像限定范围的个人帐户或组织的名称。

按名称和最新版本拉取

$ docker pull ghcr.io/NAMESPACE/IMAGE_NAME:latest
> latest: Pulling from NAMESPACE/IMAGE_NAME
> Digest: sha256:b3d3e366b55f9a54599220198b3db5da8f53592acbbb7dc7e4e9878762fc5344
> Status: Downloaded newer image for ghcr.io/NAMESPACE/IMAGE_NAME:latest
> ghcr.io/NAMESPACE/IMAGE_NAME:latest

NAMESPACE 替换为要作为映像限定范围的个人帐户或组织的名称。

构建容器映像

此示例生成 hello_docker 映像:

docker build -t hello_docker .

标记容器映像

  1. 找到要标记的 Docker 映像的 ID。

    $ docker images
    > REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
    > ghcr.io/my-org/hello_docker         latest            38f737a91f39        47 hours ago        91.7MB
    > hello-world                                           latest              fce289e99eb9        16 months ago       1.84kB
    
  2. 使用映像 ID 以及所需的映像名称和托管目标标记 Docker 映像。

    docker tag 38f737a91f39 ghcr.io/NAMESPACE/NEW_IMAGE_NAME:latest
    

NAMESPACE 替换为你希望作为映像限定范围的个人帐户或组织的名称。

标记容器映像

可以使用预定义的注释键向容器映像添加元数据,包括说明、许可证和源存储库。 支持的密钥的值将显示在映像的“包”页面中。

对于大多数映像,可以使用 Docker 标签将注释密钥添加到映像。 有关详细信息,请参阅 Docker 官方文档中的“标签”和 opencontainers/image-spec 存储库中的“预定义的注释密钥”。

对于多架构映像,可以通过将适当的注释密钥添加到映像清单中的 annotations 字段来为映像添加说明。 有关详细信息,请参阅“向多架构映像添加说明”。

Container registry 支持以下注释密钥。

密钥说明
org.opencontainers.image.source与包关联的存储库的 URL。 有关详细信息,请参阅“将仓库连接到包”。
org.opencontainers.image.description纯文本说明,限制在 512 个字符以内。 此说明将显示在包页中的包名称下方。
org.opencontainers.image.licensesSPDX 许可证标识符,如“MIT”,限制在 256 个字符以内。 许可证将显示在包页的“详细信息”边栏中。 有关详细信息,请参阅 SPDX 许可证列表

若要添加密钥作为 Docker 标签,建议在 Dockerfile 中使用 LABEL 指令。 例如,如果你是用户 octocat,拥有 my-repo,并且映像是根据 MIT 许可证的条款分发的,可以在 Dockerfile 中添加以下行:

LABEL org.opencontainers.image.source=https://github.com/octocat/my-repo
LABEL org.opencontainers.image.description="My container image"
LABEL org.opencontainers.image.licenses=MIT

注意: 如果发布链接到存储库的包,该包会自动继承链接存储库的访问权限,链接存储库中的 GitHub Actions 工作流会自动获得对包的访问权限,除非你的组织已禁用访问权限的自动继承。 有关详细信息,请参阅“配置包的访问控制和可见性”。

或者,可以使用 docker build 命令在生成时向映像添加标签。

$ docker build \
 --label "org.opencontainers.image.source=https://github.com/octocat/my-repo" \
 --label "org.opencontainers.image.description=My container image" \
 --label "org.opencontainers.image.licenses=MIT"

向多架构映像添加说明

多架构映像是支持多种体系结构的映像。 它的原理是在单一清单中引用一系列映像,其中每个映像都支持不同的体系结构。

多架构映像的“包”页面中的说明是从映像清单中的 annotations 字段获取的。 与 Docker 标签一样,注释提供了一种将元数据与映像相关联的方法,并支持预定义的注释密钥。 有关详细信息,请参阅 opencontainers/image-spec 存储库中的注释

若要为多架构映像提供说明,请在清单的 annotations 字段中为 org.opencontainers.image.description 键设置一个值,如下所示。

"annotations": {
  "org.opencontainers.image.description": "My multi-arch image"
}

例如,以下 GitHub Actions 工作流步骤生成并推送多架构映像。 outputs 参数设置映像的说明。

# 此工作流使用未经 GitHub 认证的操作。
# 它们由第三方提供,并受
# 单独的服务条款、隐私政策和支持
# 文档。

- name: Build and push Docker image
  uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
  with:
    context: .
    file: ./Dockerfile
    platforms: ${{ matrix.platforms }}
    push: true
    outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=My multi-arch image

故障排除

  • Container registry 的每个层的大小限制为 10 GB。
  • Container registry 的上传超时限制为 10 分钟。