Hub 文档

Docker Spaces

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

Docker Spaces

Spaces 允许为超出 Streamlit 和 Gradio 范围的应用使用自定义 Docker 容器。Docker Spaces 允许用户超越之前使用标准 SDK 可能实现的限制。从 FastAPI 和 Go 端点到 Phoenix 应用和 ML Ops 工具,Docker Spaces 可以在许多不同的设置中提供帮助。

设置 Docker Spaces

创建新 Space 时选择 Docker 作为 SDK 将会初始化你的 Space,方法是在你的 README.md 文件的 YAML 块中将 sdk 属性设置为 docker。或者,对于现有的 Space 仓库,在你的 Spaces README.md 文件顶部的 YAML 块中设置 sdk: docker。你也可以通过设置 app_port: 7860 来更改默认暴露的端口 7860。之后,你可以创建一个常规的 Dockerfile

---
title: Basic Docker SDK Space
emoji: 🐳
colorFrom: purple
colorTo: gray
sdk: docker
app_port: 7860
---

在内部,你可以根据需要拥有任意数量的开放端口。例如,你可以在你的 Space 中安装 Elasticsearch,并在其默认端口 9200 上在内部调用它。

如果你想将在多个端口上提供的应用暴露给外部世界,一种变通方法是使用反向代理(如 Nginx)将来自更广泛的互联网(在单个端口上)的请求分发到不同的内部端口。

Secrets 和变量管理

你可以在 Space 设置中管理 Space 的环境变量。请在此处阅读更多信息。

变量

构建时

变量在构建你的 Docker Space 时作为 build-args 传递。请阅读 Docker 的专用文档,以获得关于如何在 Dockerfile 中使用它的完整指南。

	# Declare your environment variables with the ARG directive
	ARG MODEL_REPO_NAME

	FROM python:latest
	# [...]
	# You can use them like environment variables
	RUN predict.py $MODEL_REPO_NAME

运行时

变量在运行时被注入到容器的环境中。

Secrets

构建时

在 Docker Spaces 中,出于安全原因,secrets 管理是不同的。一旦你在“设置”选项卡中创建了一个 secret,你可以通过在你的 Dockerfile 中添加以下行来暴露该 secret

例如,如果 SECRET_EXAMPLE 是你在“设置”选项卡中创建的 secret 的名称,你可以在构建时通过将其挂载到一个文件,然后使用 $(cat /run/secrets/SECRET_EXAMPLE) 读取它。

请看下面的例子

# Expose the secret SECRET_EXAMPLE at buildtime and use its value as git remote URL
RUN --mount=type=secret,id=SECRET_EXAMPLE,mode=0444,required=true \
 git init && \
 git remote add origin $(cat /run/secrets/SECRET_EXAMPLE)
# Expose the secret SECRET_EXAMPLE at buildtime and use its value as a Bearer token for a curl request
RUN --mount=type=secret,id=SECRET_EXAMPLE,mode=0444,required=true \
	curl test -H 'Authorization: Bearer $(cat /run/secrets/SECRET_EXAMPLE)'

运行时

与公共变量相同,在运行时,你可以将 secrets 作为环境变量访问。例如,在 Python 中,你将使用 os.environ.get("SECRET_EXAMPLE")。查看这个示例的 Docker Space,它使用了 secrets。

权限

容器以用户 ID 1000 运行。为了避免权限问题,你应该在任何 COPY 或下载之前创建一个用户并设置其 WORKDIR

# Set up a new user named "user" with user ID 1000
RUN useradd -m -u 1000 user

# Switch to the "user" user
USER user

# Set home to the user's home directory
ENV HOME=/home/user \
	PATH=/home/user/.local/bin:$PATH

# Set the working directory to the user's home directory
WORKDIR $HOME/app

# Try and run pip command after setting the user with `USER user` to avoid permission issues with Python
RUN pip install --no-cache-dir --upgrade pip

# Copy the current directory contents into the container at $HOME/app setting the owner to the user
COPY --chown=user . $HOME/app

# Download a checkpoint
RUN mkdir content
ADD --chown=user https://<SOME_ASSET_URL> content/<SOME_ASSET_NAME>
始终在 ADDCOPY 中指定 --chown=user,以确保新文件由你的用户拥有。

如果你仍然面临权限问题,你可能需要在你的 Dockerfile 中使用 chmodchown 来授予正确的权限。例如,如果你想使用目录 /data,你可以这样做

RUN mkdir -p /data
RUN chmod 777 /data

你应该始终避免多余的 chown。

更新文件的元数据会创建一个新副本,存储在新层中。因此,递归的 chown 可能会由于所有受影响文件的重复而导致非常大的镜像。

与其通过运行 chown 来修复权限

COPY checkpoint .
RUN chown -R user checkpoint

你应该始终这样做

COPY --chown=user checkpoint .

ADD 命令也一样)

数据持久性

每当你的 Docker Space 重新启动时,写入磁盘的数据都会丢失,除非你选择持久存储升级。

如果你选择持久存储升级,你可以使用 /data 目录来存储数据。此目录挂载在持久卷上,这意味着写入此目录的数据将在重启后保留。

目前,/data 卷仅在运行时可用,即你不能在 Dockerfile 的构建步骤期间使用 /data

在某些特定情况下,你也可以使用我们的 Datasets Hub,你可以在 git LFS 仓库中存储状态和数据。你可以在此处找到持久性的示例,该示例使用 huggingface_hub以编程方式将文件上传到数据集仓库。这个 Space 示例以及本指南将帮助你确定哪种解决方案最适合你的数据类型。

最后,在某些情况下,你可能希望从你的 Space 代码中使用外部存储解决方案,例如外部托管数据库、S3 等。

使用 GPU 的 Docker 容器

您可以使用我们支持 GPU 的 Spaces Hardware 运行带有 GPU 支持的 Docker 容器。

我们建议使用 Docker Hub 上的 nvidia/cuda 作为基础镜像,它预装了 CUDA 和 cuDNN。

在 Docker 构建时,您无法访问 GPU 硬件。因此,您不应尝试在 Dockerfile 的构建步骤中运行任何与 GPU 相关的命令。例如,在构建镜像时,您无法运行 nvidia-smitorch.cuda.is_available()。请此处阅读更多信息。

阅读更多

< > 在 GitHub 上更新