Serverless 部署(Knative)
在 Knative 体系的函数平台上部署 Halo Server:准备镜像、设置环境变量、挂载 NFS 持久卷、分配资源,并避开扩缩容的坑。
把 Halo Server 部署到 Knative 体系的 Serverless 函数平台。镜像用 Halo 主仓库 deploy/server/ 里的 Dockerfile 构建,做法见 Docker 部署。
镜像做了什么
deploy/server/Dockerfile 在构建时完成三件事:
- 重组应用包:
npm run build:server生成的 linux-x64 应用被拆成小于 90 MB 的分片(bundle/halo-bundle.tgz.part-*,便于放进 git 仓库),构建时重新拼接并解压到/app/linux-unpacked。 - 安装系统库与字体:用 apt 安装 Chromium 和 Electron 依赖的 GTK、X11、nss 等库,以及中文字体(文泉驿微米黑)。slim 基础镜像不带字体,缺了它文字会显示成空白。
- 设置运行时默认值:
HALO_SERVER_MODE=1、PORT=8080、HOME=/tmp(没有设置HALO_DATA_DIR时数据写在/tmp/.halo),由 tini 启动主进程。
基础镜像是公共镜像 python:3.12-slim-bookworm(Debian 12)。需要换成你环境里可达的等价镜像时,改 Dockerfile 的 FROM,并保证构建环境能拉取它。
部署步骤
1. 准备镜像
任选一种:
- 推送镜像(推荐):按 Docker 部署 在本地构建镜像,推送到平台能访问的镜像仓库,再用这个镜像创建服务。
- 由平台从 git 构建:把
deploy/server/的文件连同生成的bundle/放进你自己的私有 git 仓库(bundle/已按小于 90 MB 分片),把平台的代码源指向这个仓库。选择用 Dockerfile 构建,Dockerfile 路径为仓库根目录的./Dockerfile。构建时需要联网安装系统库。
2. 设置环境变量
在平台的环境变量配置中填入下列变量,含义见 Halo Server 配置:
| 环境变量 | 建议值 |
|---|---|
HALO_DATA_DIR | /data,指向下一步挂载的 NFS |
HALO_REMOTE_PASSWORD | 8–64 位随机密码,例如 openssl rand -hex 24 的输出 |
HALO_AI_PROVIDER | 你的模型协议族,如 openai |
HALO_AI_API_URL | 你的模型网关地址 |
HALO_AI_API_KEY | 网关密钥 |
HALO_AI_MODEL | 模型名 |
镜像已设置 HALO_SERVER_MODE=1 和 PORT=8080。平台要求特定端口时,设置 PORT 并让平台路由到同一端口。
3. 把 NFS 持久卷挂到 HALO_DATA_DIR
在平台的存储或卷挂载配置中,创建或选择一块 NFS 卷,挂载到容器内的 /data,并确保 HALO_DATA_DIR=/data 与之一致。
不挂载就会丢数据
没有设置 HALO_DATA_DIR 时,数据写在 /tmp/.halo,实例回收后被清空。生产环境必须挂载 NFS 卷,并把 HALO_DATA_DIR 指向挂载点。
4. 分配资源
Halo Server 运行完整的 Electron(Chromium)主进程,内存需求较大。
| 资源 | 建议 |
|---|---|
| 内存 | 至少 4–8 GB,过低会被系统终止(OOM) |
| CPU | 至少 2 核 |
请给单个实例分配充足的资源,而不是靠多个实例分摊,原因见下文。
5. 暴露端口
把服务的对外端口设为容器的 8080,或你设置的 PORT。
路径前缀
平台通常把服务挂在某个路径前缀下(如 /fc-xxxx/)。网页版会自动适配这个前缀;调用 API 时,把平台给出的带前缀地址当作基础地址,在后面拼接 /api/... 和 /ws 即可。
并发与扩缩容
有状态的单实例服务,不要横向扩容
Halo Server 的状态由 SQLite、本地文件和内存中的会话共同构成,三者都绑定在单个实例上。
- 不要横向扩容:多个实例各持一份独立状态,会造成数据不一致;多个实例同时写 NFS 上的同一份 SQLite 还会损坏数据库。把最大实例数限制为 1。
- 纵向扩容:提高单个实例的 CPU 和内存来承载更高负载。
- 缩容到零后的冷启动是一次完整的重新初始化:内存中的会话会丢失(持久化数据从 NFS 恢复),Electron 冷启动也需要可观的时间。对延迟敏感的场景,请关闭缩容到零,保持至少 1 个常驻实例。
验证
用平台给出的服务地址(含路径前缀)访问公开的状态接口:
curl https://<PLATFORM_HOST>/<PATH_PREFIX>/api/remote/status输出:
{"success":true,"data":{"active":true,"clients":0,"version":"1.0.0"}}再校验访问密码:
curl -X POST https://<PLATFORM_HOST>/<PATH_PREFIX>/api/remote/login \
-H "Content-Type: application/json" \
-d '{"token":"<YOUR_ACCESS_PASSWORD>"}'输出:
{"success":true}<PLATFORM_HOST> 和 <PATH_PREFIX> 换成平台给出的域名和路径前缀。构建失败时,先检查基础镜像是否可达,以及构建环境的磁盘空间是否够放下重组后的应用包。
下一步
- Halo Server 集成指南:把数字人接入你的业务系统
- HTTP API 概览:基础地址、鉴权和错误约定