Docker Spaces
Spaces 可以容纳自定义的 Docker 容器,用于超出 Streamlit 和 Gradio 范围的应用程序。Docker Spaces 允许用户突破以前使用标准 SDK 才能实现的限制。从 FastAPI 和 Go 端点到 Phoenix 应用程序和 ML Ops 工具,Docker Spaces 可以帮助您在许多不同的设置中进行部署。
设置 Docker Spaces
在 创建新的 Space 时,选择**Docker** 作为 SDK 将通过在 README.md
文件的 YAML 块中将 sdk
属性设置为 docker
来初始化您的 Space。或者,对于现有的 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 这样的反向代理来分发来自更广泛的互联网(在一个端口上)到不同内部端口的请求。
密钥和变量管理
您可以在 Space 设置中管理 Space 的环境变量。阅读更多 此处。
变量
构建时
在构建 Docker Space 时,变量作为 build-arg
传递。阅读 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
运行时
变量在运行时注入容器的环境中。
密钥
构建时
在 Docker Spaces 中,出于安全原因,密钥管理有所不同。在 设置选项卡 中创建密钥后,您可以通过在 Dockerfile 中添加以下行来公开该密钥
例如,如果 SECRET_EXAMPLE
是您在设置选项卡中创建的密钥的名称,则可以通过将其挂载到文件,然后使用 $(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)'
运行时
与公共变量相同,在运行时,您可以像环境变量一样访问密钥。例如,在 Python 中,您将使用 os.environ.get("SECRET_EXAMPLE")
。查看此 示例,它演示了使用密钥的 Docker Space。
权限
容器以用户 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>
ADD
和 COPY
指定 --chown=user
,以确保新文件归您的用户所有。如果您仍然遇到权限问题,您可能需要在您的Dockerfile
中使用chmod
或chown
来授予正确的权限。例如,如果您想使用/data
目录,您可以执行以下操作:
RUN mkdir -p /data
RUN chmod 777 /data
您应该始终避免不必要的chown操作。
而不是通过运行chown
来修复权限
COPY checkpoint .
RUN chown -R user checkpoint
您应该始终执行以下操作:
COPY --chown=user checkpoint .
(ADD
命令也一样)
数据持久化
除非您选择升级到持久存储,否则每次您的Docker Space重启时,写入磁盘的数据都会丢失。
如果您选择升级到持久存储,则可以使用/data
目录来存储数据。此目录挂载到持久卷上,这意味着写入此目录中的数据将在重启后仍然保留。
目前,/data
卷仅在运行时可用,即您无法在Dockerfile的构建步骤中使用/data
。
对于特定情况,您也可以使用我们的数据集中心,您可以在其中将状态和数据存储在git LFS存储库中。您可以在这里找到一个持久化的示例这里,它使用huggingface_hub
库以编程方式将文件上传到数据集存储库。此Space示例以及本指南将帮助您确定哪种解决方案最适合您的数据类型。
最后,在某些情况下,您可能希望从Space的代码中使用外部存储解决方案,例如外部托管数据库、S3等。
带有GPU的Docker容器
您可以通过使用我们其中一个支持GPU的Spaces硬件来运行支持GPU的Docker容器。
我们建议使用Docker Hub中的nvidia/cuda
作为基础镜像,它预装了CUDA和cuDNN。
nvidia-smi
或torch.cuda.is_available()
。阅读更多[此处](https://github.com/NVIDIA/nvidia-docker/wiki/nvidia-docker#description)。