> ## Documentation Index
> Fetch the complete documentation index at: https://starforge.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 离线内网部署

> 在没有 Hugging Face、PyPI 和公共镜像仓库出口的网络里跑 StarForge。

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
FORGE_HF_ENDPOINT=https://mirrors.your-company.com/repository/huggingface
```

这一项设置就是权重下载能在镜像后面工作的原因。本页剩下的内容是另外三样会坏掉的东西，以及各自怎么办。

## 模型权重

`huggingface_hub` 读 `HF_ENDPOINT`，而平台会把 `FORGE_HF_ENDPOINT` 原样注入每个训练容器和
Playground 容器。把它指向一个反向代理即可——Nexus、Artifactory，或者任何能代理 Hub 的东西。

有两项调整会自动跟着一起生效，它们的存在都是因为某种极难诊断的失败：

<AccordionGroup>
  <Accordion title="超时被放宽" icon="clock">
    `huggingface_hub` 默认十秒超时。镜像第一次取一个它从未缓存过的文件时要一路回源，
    这经常超过十秒。症状是冷文件下载失败、重试又成功，看起来像网络不稳定，而不像配置问题。
  </Accordion>

  <Accordion title="Xet 被关闭" icon="ban">
    Xet 需要短时效 token，而反向代理签不出来。不关的话，权重下载会卡在一个 400 上，
    而那个响应体里除了一个 URL 什么都没有——没有消息、没有字段，连搜都没得搜。

    如果你的镜像确实实现了 Xet，用 `FORGE_PASSTHROUGH_ENV` 显式覆盖。
  </Accordion>
</AccordionGroup>

<Warning>
  拉不到权重的作业不会快速失败。它会启动、打印下载日志，然后一直卡到超时——
  整个过程都占着它的 GPU 分配。在向团队开放提交之前，先确认镜像是通的。
</Warning>

## 容器镜像

训练镜像来自 recipe catalog，而 catalog 里写的是 `nvcr.io` 这类公共仓库。内网里需要先转存再重定向：

| 设置                               | 作用                                             |
| -------------------------------- | ---------------------------------------------- |
| `FORGE_RUNTIME_REGISTRY_FILE`    | 把 `runtime_id` 映射到你的仓库里实际存在的工件，覆盖 catalog 里的地址 |
| `FORGE_ALLOWED_IMAGE_REGISTRIES` | 用户用 `--image` 时允许的主机，设成你的内网仓库                  |
| `FORGE_K8S_IMAGE_PULL_SECRET`    | KubeRay 下的拉取凭据                                 |

生产环境用 digest 而不是 tag。在你自己的镜像仓库里挪动的 tag，仍然是一个挪动过的 tag。

## 在镜像站后面构建镜像

Dockerfile 默认走公共上游，所以在哪都能构建。用 build 参数把它指向内网镜像站：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
docker build \
  --build-arg APT_MIRROR=https://mirrors.your-company.com/repository \
  --build-arg PYPI_INDEX=https://mirrors.your-company.com/repository/pypi-group/simple/ \
  --build-arg NPM_REGISTRY=https://mirrors.your-company.com/repository/npm-group/ \
  --build-arg UV_IMAGE=mirror.your-company.com/astral-sh/uv:python3.13-trixie-slim \
  -t starforge-console:0.3.0 .
```

`APT_MIRROR` 留空就保持 Debian 自己的源——能正常访问互联网的机器上你要的就是这个。

## 平台运行时

作业侧需要 `starforge` 才能回传指标，而训练镜像里不会有它。

默认的 `FORGE_JOB_RUNNER_MODE=bundled` 不需要任何网络就解决了这件事：
服务端把一个内容寻址的 PEX 注入作业，训练镜像不需要预装任何东西。
这是少数几个「离线反而更简单」的地方——这项设置保持默认就好。

## 数据集

这里没有任何东西需要访问互联网。数据集用 `sf dataset push` 推进部署自己的对象存储，
作业启动时拉进共享缓存。见[数据集](/zh-Hans/guides/datasets)。

## 确认成功

提交快速开始里那个作业，看日志。你要看到的顺序是：

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
resolving Qwen/Qwen2.5-1.5B via https://mirrors.your-company.com/repository/huggingface
downloading model-00001-of-00002.safetensors
...
Ray runtime started
```

卡在第一行和第二行之间是镜像的问题。响应体里只有一个裸 URL 的 400 是 Xet。
大文件在大约十秒后超时，说明放宽的超时没有生效——检查设置 `HF_ENDPOINT` 的是平台，而不是你自己的脚本。
