# 容器镜像

容器镜像是 Hugging Face Hub 上用于 Docker 及其他 [OCI](https://opencontainers.org/) 镜像的仓库类型。Hugging Face 容器注册表 `cr.hf.co` 将镜像存储在 [Xet](./xet/index) 存储后端上。请使用推荐的客户端 [`hf image`](#pushing-and-pulling-with-hf-image) 来推送和拉取镜像；Docker、Podman、crane、skopeo、ORAS 和 Helm 等标准客户端同样适用。

> [!NOTE]
> 容器镜像目前处于私有测试阶段：[联系我们](https://huggingface.co/contact/sales)即可为您的组织启用该功能。

## 创建仓库

前往 [huggingface.co/new-container](https://huggingface.co/new-container)，选择组织、名称和可见性。或者使用 API：

```bash
curl -X POST https://huggingface.co/api/containers/my-org/my-app \
  -H "Authorization: Bearer $HF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"private": true}'
```

在推送之前创建仓库：向不存在的仓库推送会失败并返回 `NAME_UNKNOWN`。其页面 `https://huggingface.co/containers/my-org/my-app` 列出了其标签。谁可以拉取和推送取决于仓库的可见性以及每位成员在组织中的角色。

## 使用 `hf image` 推送和拉取

[`hf image`](https://github.com/huggingface/hf-image) 是 `hf` CLI 的扩展，它仅传输自上一版本以来每个层中发生变化的部分，因此与其他 OCI 客户端相比，能带来更快的体验。

```bash
hf extensions install hf-image
hf auth login                                   # or set HF_TOKEN
hf image build -t cr.hf.co/my-org/my-app:v2 .   # optional: docker build works too
hf image push cr.hf.co/my-org/my-app:v2
hf image pull cr.hf.co/my-org/my-app:v2
```

它使用您的 Hugging Face [用户访问令牌](./security-tokens)（拉取需要 `read`，推送需要 `write`），并且需要支持 [containerd 镜像存储](https://docs.docker.com/engine/storage/containerd/) 的 Docker。通过 `hf image` 推送的镜像可被任意客户端拉取。

由于 `hf image` 以未压缩格式存储层，其推送的镜像摘要与使用 `docker push` 时不同。若需保留 `docker push` 的摘要（例如用于签名或按摘要固定的部署），请使用 `hf image push --preserve-digests`。此操作速度较慢：更改的层将像使用 `docker push` 一样被完整推送和拉取。

## 使用 Docker 和其他 OCI 客户端

虽然我们建议使用 `hf image`（参见上一节）以充分利用 [Xet 后端](./xet/index)，但您也可以通过任何 OCI 客户端与注册表进行交互。

使用您的 Hugging Face 用户名和 [User Access Token](./security-tokens) 作为密码登录：`read` 用于拉取，`write` 用于推送。公共镜像无需登录即可拉取。

```bash
echo $HF_TOKEN | docker login cr.hf.co -u <username> --password-stdin
docker tag my-app cr.hf.co/my-org/my-app:v1
docker push cr.hf.co/my-org/my-app:v1
docker pull cr.hf.co/my-org/my-app:v1
```

其他 OCI 客户端的工作方式相同。Helm 会将图表名称附加到 URL 末尾：`helm push mychart-0.1.0.tgz oci://cr.hf.co/my-org` 会推送到 `my-org/mychart`，该路径必须事先存在。

## 删除图像

在 Hub 上，可以在图像或标签的页面中，通过其菜单中的 **删除此标签** 来移除标签。使用 [`hf image`](#pushing-and-pulling-with-hf-image) 时，先移除图像的标签，然后按摘要（digest）将其删除：

```bash
hf image untag cr.hf.co/my-org/my-app:v1                # prints the image's digest
hf image delete cr.hf.co/my-org/my-app@sha256:<digest>
```

如果仍有其他内容（例如另一个标签）引用该镜像，删除操作将被拒绝，并列出需要先移除的内容。删除多架构镜像时，其平台镜像也会被一并删除。

## 垃圾回收

注册表会删除不再被任何标签指向的镜像，无论是直接指向还是通过多架构镜像间接指向，例如新推送后旧的 `latest`。它还会删除未被任何剩余镜像使用的层。若要继续通过摘要拉取镜像，请为其保留一个标签。

## 限制

- 图像名称为 `cr.hf.co/<namespace>/<name>`，且使用小写字母。
- 层大小上限为 100 GB，清单大小上限为 4 MiB。
- 标签列表可能需要几秒钟才能显示新标签。

