跳到主要内容

环境变量

环境变量是模板配置其中工作负载的方式:一个 Hugging Face 令牌、一个模型名称、一个日志级别。在模板表单的环境部分添加它们,每行一个键和一个值,右侧带一个私密开关。

如何设置

组成部分规则
最多 256 个字符。键为空的行会在保存时被丢弃。
任意字符串。留空则该条目被存储为未设置。
私密对所属组织之外的任何人遮蔽该值。

没有值的条目根本不会被注入容器。这让它很适合当占位符:把 HF_TOKEN 声明为没有值的私密条目,模板就说明了租用者必须提供什么,同时又不会把令牌送给每一个读它的人。

在 API 中,env 是 POST /v1/templatesPATCH /v1/templates/{id} 上的一个对象列表:

{
"env": [
{ "key": "MODEL_ID", "value": "meta-llama/Llama-3-8B", "secret": false },
{ "key": "HF_TOKEN", "value": null, "secret": true }
]
}

在 PATCH 中发送 env 会替换整个列表。没有按单个键更新的方式。

私密值遮蔽

私密值只会返回给拥有该模板的组织。其他所有人——包括浏览你公开模板的人,也包括精选 system 模板的读者——拿到的是 value: nullsecret 标志保持不变。控制台会显示键名,并用隐藏占位符代替值。

遮蔽跟随数据,而不是跟随端点:GET /v1/templatesGET /v1/templates/{id}GET /v1/templates/by-hash/{hash_id} 都会应用它。

有两个后果值得知道:

  • 复制一个不属于你的组织的模板时,副本中的每个私密值都会被清空。你从来没有读取它们的权限,成为副本的所有者不能改变这一点。复制你自己的模板则会保留它们。
  • 把一个已存在的值标记为私密,只能从此以后隐藏它,并不能收回已经读到它的人手里的内容。请改为轮换该凭据。

部署时的租用者覆盖

部署时可以用 POST /v1/instances 上的 env_overrides 添加或替换环境变量条目:

{
"offer_id": "…",
"template_id": "…",
"disk_gb": 100,
"env_overrides": [{ "key": "HF_TOKEN", "value": "hf_…", "secret": true }]
}

先应用模板环境变量,再应用覆盖项,按键匹配——覆盖项胜出。任意一侧值为 null 的条目会被丢弃,而不是作为空字符串注入。这就是你在不编辑模板的情况下填上私密占位符的办法,同时也让你的令牌不进入共享的配方。

平台覆盖层总是胜出

在模板环境变量与租用者覆盖合并之后,Superheat 会应用一层平台覆盖,而这层覆盖是最后应用的。覆盖层里的键无法被模板值或 env_overrides 条目压过——你设的任何值都会被无声地替换掉。

变量何时设置携带内容
CONTAINER_ID始终工作负载标识符
GPU_COUNT始终分配给该实例的 GPU 数量
SUPERHEAT_TCP_PORT_<n>每个已发布的 TCP 端口一个容器端口 <n> 映射到的主机端口
PUBLIC_KEYsshjupyter,且部署时附加了 SSH 密钥你的 SSH 公钥
SUPERHEAT_SSH_PUBLIC_KEYSsshjupyter,且部署时附加了 SSH 密钥同样的密钥内容,采用换行分隔的形式
SUPERHEAT_ONSTARTsshjupyter,且已设置时启动脚本的内容
OPEN_BUTTON_PORTsshjupyter,且有端口标签为 open打开按钮的目标端口
JUPYTER_TOKENjupyter平台生成的访问令牌
JUPYTER_PORTjupyter8080
JUPYTER_DIRjupyter模板的 Jupyter 工作目录
JUPYTER_LABjupytertrue 表示 JupyterLab,false 表示经典 notebook

所以在模板上设置 JUPYTER_TOKEN 毫无作用:令牌由平台生成,好让它能拼出打开按钮的 URL,而这个令牌从不回传。设置 GPU_COUNT 同样没用——它反映的是你实际租到的切片,如果租用者能改它,信任这个值的程序就会被骗。

不要用覆盖层的键名来命名模板变量

覆盖是无声的。如果你的代码读 GPU_COUNT 时期待的是你自己的值,它拿到的会是平台的值,而且哪里都不会报错。

在容器内你看到的是什么

在派生自基础镜像的镜像上,sshd 和 Jupyter 会启动不继承容器进程环境的登录 shell,因此入口点会把环境写入 /etc/environment/etc/profile.d/superheat-env.sh。你 SSH 进去时,你的变量以及 CONTAINER_IDGPU_COUNTSUPERHEAT_TCP_PORT_* 条目都在那里。

预置阶段的机密被有意地从这两个文件中排除:SUPERHEAT_ONSTARTJUPYTER_TOKENPUBLIC_KEYSUPERHEAT_SSH_PUBLIC_KEYS 由入口点消费,从不重新导出。在 SSH 会话里 echo $JUPYTER_TOKEN 什么都不会返回,这是设计使然。