visual-journal / docs /deployment /huggingface-space-free.md
Visual Journal deploy
Deploy 8e0aeb3 to Docker Space
84810e9
|
Raw
History Blame Contribute Delete
17.6 kB

Hugging Face Space 部署

本文档描述如何把本项目部署到 Hugging Face Docker Space,用作公网图片生成服务。Docker Space 的创建和更新权限取决于 Hugging Face 的当前账户政策;固定目标已存在且元数据标识为 Docker,部署脚本会直接使用认证 Git 推送,避免 hf upload 触发创建接口的已知 402。这不绕过新建 Docker Space 的账户限制。

目标形态

  • 手机浏览器可以访问 Space 网页并正常生图。
  • 电脑上的 Agent 可以通过 /api/agent/* 调用同一个 Space 生图。
  • 首战场景是中文内容运营者为小红书笔记、商品详情页或活动海报生成首版视觉稿,不是公开 SaaS。
  • 状态后端使用 memory,不依赖 SQLite、PostgreSQL 或外部数据库。
  • 图片 Web 结果优先保存在浏览器 IndexedDB,减少服务端临时盘依赖。

Space README YAML

本仓库顶层 README.md 已包含 Hugging Face Space metadata。如果你维护的是单独的 Space 仓库,确认它的 README.md 顶部使用 Docker SDK,并暴露本项目端口:

---
sdk: docker
app_port: 4783
---

官方依据:

全新电脑前置条件

全新用户、全新电脑需要先准备系统级工具。没有 Node.js 和 npm 时,仓库内 npm 脚本无法运行;没有 HF CLI 登录时,脚本无法把 Secret 写到远端 Space。

先检查:

node --version
npm --version
hf --help
hf auth whoami

要求:

  • Node.js >=22.15.0。
  • npm 随 Node.js 一起可用。
  • Hugging Face CLI 使用当前官方 hf 命令。
  • hf auth login 使用 Hugging Face Access Token,不是账号密码。
  • Docker 只对本地 Space-like 容器 smoke(推荐 npm run smoke:hf-space-local,兼容别名 npm run smoke:hf-space)和本地容器验证必需;远端部署由 npm run deploy:space 统一执行。

安装 Hugging Face CLI 时,以官方文档为准。不要把远程安装脚本直接管道到 shell;如需使用官方脚本,先下载、核对来源和内容后再执行。

第一次拉取仓库后安装依赖:

npm run install-scripts:check
npm run npm-install-policy:check
npm ci --strict-allow-scripts
npm run dependencies:check

项目支持 Node.js >=22.15.0;本地先校验锁文件中的安装脚本白名单,并确认 npm 支持 --strict-allow-scripts,完成确定性安装后核对直接依赖。旧 npm 会被安装门禁明确拒绝,升级 npm 后再重试。GitHub Actions 和 Docker 使用 Node 26,并额外启用 npm 的 --strict-allow-scripts

如果不确定当前机器缺什么,运行只读诊断:

npm run doctor

doctor 会检查 Node、npm、hf CLI、HF 登录状态、node_modules、git、Docker、固定 Space 目标、远端 Variables 和远端 Secrets。该命令不会写远端 Secret、不会重启 Space、不会打印 Secret 值。

管理员命令中心

本仓库只保留一组稳定管理员入口:

npm run status
npm run doctor
npm run verify
npm run deploy:local
npm run deploy:space
npm run agent:doctor
  • status:只读输出 git、Node、固定 Space 目标、Agent capabilities 路径和 Skill 入口。
  • doctor:统一诊断入口,默认包含 HF Space 只读远端检查,并校验当前 npm 是否支持严格安装脚本策略、本地 node_modules 隐藏锁文件和直接依赖版本是否与根锁文件一致。
  • verify:提交前基线,先核对锁文件安装脚本与 allowScripts 白名单、当前 npm 严格安装策略能力和已安装直接依赖,再执行测试、lint、脚本语法、构建和 git diff --check;需要真实 PostgreSQL gate 时加 --postgres
  • deploy:local:拒绝脏工作区后重建本地 Docker 服务,等待 healthcheck、核验镜像 revision 并探测真实 HTTP 端点;加 --memory 会断言 memory/indexeddb overlay 生效,加 --postgres 会断言 postgres/fs overlay 生效且要求通过 shell 或 Compose .env 提供 GPT_IMAGE_POSTGRES_PASSWORD。默认 Compose 只绑定 127.0.0.1:4783;需要非回环发布时必须显式设置 GIP_BIND_HOSTAPP_PASSWORD
  • deploy:space:上传当前干净 git HEAD 到固定 HF Space,并做只读公网验证;已存在 Docker Space 根据远端元数据直接使用认证 Git 推送,其他类型才优先尝试 hf upload
  • agent:doctor:通过仓库 Skill 脚本执行只读 Agent API 契约检查,不触发真实生图。

HF Space 交互使用官方 hf CLI。不要维护本机 access 文件,不要把 APP_PASSWORDAGENT_API_TOKEN、OpenAI Key 或 Hugging Face token 写入仓库文件。

部署当前干净的 git HEAD 到固定 Space:

npm run deploy:space

该脚本会:

  • 使用 git status --porcelain 拒绝脏工作区。
  • 使用 git archive HEAD 生成临时源码目录,只上传已跟踪源码。
  • Space 发布包会排除根目录 readme-images/ 中的 README 文档截图,以兼容 Hugging Face Git 的二进制文件门禁;Space README 会改用对应 GitHub 提交的不可变图片地址。
  • 读取远端 Space 元数据;当前固定 Docker Space 直接克隆、同步已跟踪源码并使用认证 Git 推送。
  • 非 Docker Space 才优先使用 hf upload;仅当它命中既有 Docker Space 创建政策 402 时才回退到认证 Git 推送,其他错误不会自动回退。
  • 等待新 Space commit 进入 RUNNING
  • 检查 /api/auth-status/api/agent/capabilities/api/runtime-capabilities,不触发真实生图。

配置或轮换 Variables/Secrets 时,直接使用官方 hf CLI:

hf spaces variables add misonL/visual-journal -e AGENT_STATE_BACKEND=memory
hf spaces variables add misonL/visual-journal -e NEXT_PUBLIC_IMAGE_STORAGE_MODE=indexeddb
hf spaces variables add misonL/visual-journal -e APP_LOG_LEVEL=warn
hf spaces secrets add misonL/visual-journal -s APP_PASSWORD=<page-access-code>
hf spaces secrets add misonL/visual-journal -s AGENT_API_TOKEN=<long-random-agent-token>

源码部署、远端诊断、Variables 和 Secrets 都由仓库命令与 hf CLI 协同完成;部署回退只使用现有 Git 凭据,不维护第二套 access-file 或 Secret 同步流程。

Space Variables

在 Space Settings 中添加这些 Variables:

AGENT_STATE_BACKEND=memory
NEXT_PUBLIC_IMAGE_STORAGE_MODE=indexeddb
APP_LOG_LEVEL=warn

NEXT_PUBLIC_IMAGE_STORAGE_MODE 是构建期和运行期都需要的值。Dockerfile 已声明 build arg,Hugging Face Docker Space 会把同名 Variable 作为 build arg 传入构建,并在运行期注入环境变量。

如果不使用 memory,再按实际状态后端追加可选变量:

AGENT_SQLITE_PATH=generated-images/.agent-state/agent.sqlite
AGENT_DATABASE_URL=postgres://...
AGENT_DB_PASSWORD=<database-password>
AGENT_DB_PASSWORD_FILE=/path/to/password-file

AGENT_DATABASE_URLAGENT_DB_PASSWORDAGENT_DB_PASSWORD_FILE 是 PostgreSQL 配置路径,不需要在 memory 模式下设置为空值。

可选:

AGENT_PUBLIC_BASE_URL=https://<user>-<space>.hf.space

AGENT_PUBLIC_BASE_URL 影响 OpenAPI servers[0].url,也用于 POST /api/agent/artifacts/{id}/share 返回用户可打开的分享外链。必须填写绝对 http/https URL,不能包含凭据、查询参数或片段;Agent skill 仍应以 GPT_IMAGE_PLAYGROUND_URL 指向实际 Space 地址。

Space Secrets

在 Space Settings 中添加 Secrets,不要写入仓库文件:

OPENAI_API_KEY=<your-api-key>
OPENAI_API_BASE_URL=https://api.openai.com/v1
# 可选:仅服务端到上游的无认证 HTTP(S) 代理。
OPENAI_UPSTREAM_PROXY_URL=http://proxy.internal:8080
APP_PASSWORD=<page-access-code>
AGENT_API_TOKEN=<long-random-agent-token>

OPENAI_API_BASE_URLOPENAI_CHANNEL_N_BASE_URL 必须是无凭据、无查询参数和无片段的 httphttps 绝对地址,通常以 /v1 结尾。公网 Space 推荐使用 https 上游;只有内网、专用代理或已确认的兼容渠道需要 http 时才配置 http

OPENAI_UPSTREAM_PROXY_URL 只影响 Space 服务端到上游 API 的出站连接,不影响用户浏览器访问 Space。它仅接受无认证、无路径、无查询参数和无片段的 http://https:// 根代理地址,不支持 SOCKS。多渠道部署可用 OPENAI_CHANNEL_N_PROXY_URL 覆盖全局代理,渠道级值优先。代理地址即使不含凭据也建议作为 Space Secret 管理;修改后需要重新启动或重新部署 Space。运行态和 Agent 诊断只公开是否配置及协议,不公开主机或端口。

公网部署建议至少设置访问码 APP_PASSWORDAGENT_API_TOKEN。如果不设置 APP_PASSWORD,任何人都可以打开网页并消耗服务端 API Key。

如果要把这个 Space 当成客户可见的公网服务,npm run doctor:hf-spaceremote-secrets 必须通过,且应同时看到 APP_PASSWORDAGENT_API_TOKEN 已配置。没有这两个值时,只适合本地或受控内网试用,不适合直接给客户公开。

如果使用服务端渠道池,改用 OPENAI_CHANNEL_N_* Secrets:

OPENAI_ROUTING_STRATEGY=round_robin
OPENAI_CHANNEL_1_ID=official
OPENAI_CHANNEL_1_BASE_URL=https://api.openai.com/v1
OPENAI_CHANNEL_1_API_KEYS=<key-a>,<key-b>
# 可选:仅覆盖此渠道的全局上游代理。
OPENAI_CHANNEL_1_PROXY_URL=http://channel-proxy.internal:8080

手机网页使用

  1. 打开 Space 地址,例如 https://<user>-<space>.hf.space
  2. 如果配置了 APP_PASSWORD,输入页面访问码。
  3. 直接填写提示词并生图。若 Space 没有配置服务端 API Key,也可以在右上角 API 设置 中填写自己的 API Key 和 API URL。
  4. NEXT_PUBLIC_IMAGE_STORAGE_MODE=indexeddb 时,图片结果保存在当前浏览器 IndexedDB。换设备、清理浏览器数据或隐私模式退出后,本地历史可能消失。

电脑 Agent API 使用

先做只读契约检查,不触发真实生图:

GPT_IMAGE_PLAYGROUND_URL=https://<user>-<space>.hf.space \
GPT_IMAGE_AGENT_TOKEN=<agent-token> \
GPT_IMAGE_AGENT_CONTRACT_CHECK=1 \
node skills/gpt-image-playground-agent/scripts/generate-image.mjs

真实文生图:

GPT_IMAGE_PLAYGROUND_URL=https://<user>-<space>.hf.space \
GPT_IMAGE_AGENT_TOKEN=<agent-token> \
node skills/gpt-image-playground-agent/scripts/generate-image.mjs \
  --allow-billable \
  "a product photo of a ceramic mug on a wooden table"

脚本会先读取 GET /api/agent/capabilities,再调用 Agent API。成功响应会保留相对 content_url,同时补充 absolute_content_urlabsolute_metadata_url,便于在桌面环境直接下载产物。

远端 Agent 调用不要硬编码路径。普通文生图默认提交业务意图到 capabilities 声明的 orchestration.endpoint,由服务端选择内部执行路径、上游 request mode 和轮询方式;Agent 客户端不按尺寸、远端 HTTPS 或流式参数自行选择 Images、Responses、SSE 或非流式路径。显式 page_sse 诊断、默认 WebP edit、高分辨率 edit 和复杂批量仍按 Skill 规则使用页面端 /api/images SSE;页面流式失败或不可用时,先诊断结构化错误,再用新的 Idempotency-Key 显式选择 Agent JSON、Agent edit 或 job 路径对照。job polling 只在显式选择时使用。需要诊断对照时可用 --agent--streaming-strategy off 强制 Agent JSON,也可用 --page-sse--job 显式选择路径。

如果 Space 同时配置了 APP_PASSWORDAGENT_API_TOKEN,Agent JSON 端点用 GPT_IMAGE_AGENT_TOKEN 发送 Bearer token;页面端 /api/images SSE 仍按 capabilities 的 agent_streaming.page_sse.auth 判断,可能需要额外设置 GPT_IMAGE_APP_PASSWORD_HASH,并通过 form-data passwordHash 发送页面访问码哈希。页面 SSE 会把业务 key 写入 clientRequestId,长度上限以 capabilities 中的 agent_streaming.page_sse.client_request_id.max_length 为准。

本地 HF 近似 smoke

提交前运行:

npm run smoke:hf-space-local

该命令会:

  • 使用 NEXT_PUBLIC_IMAGE_STORAGE_MODE=indexeddb 构建 Docker 镜像。
  • AGENT_STATE_BACKEND=memory 启动临时容器。
  • 用手机 User-Agent 检查首页可访问。
  • 检查 /api/agent/capabilities 返回 state_backend=memoryimage_storage_mode=indexeddb
  • 默认等待容器 HTTP ready 最多 45 秒;慢机器可设置 HF_SPACE_SMOKE_READY_TIMEOUT_MS=90000
  • 执行 Agent 生成和编辑脚本的契约检查,不触发真实上游生图。

平台与运行限制

  • Docker Space 的创建、更新和可用硬件受 Hugging Face 当前账户政策约束。hf upload 对已存在 Space 的创建接口检查收到 402 时,脚本会尝试认证 Git 推送;新建 Docker Space 仍需要满足平台账户要求。
  • CPU Basic 适合公开演示和轻量使用,不适合长期高并发;长时间无访问后可能休眠。需要真正永不休眠或自定义 sleep time 时,应使用满足平台要求的付费硬件。
  • Docker Space 重启后容器磁盘写入会丢失。memory 状态后端的 Agent 幂等记录、replay 状态和分享元数据也会丢失。
  • Agent API 仍会把产物图片写入容器临时文件系统,以便提供 content_url 下载。重启后这些链接不保证继续有效。
  • 需要长期保存图片、分享链接或 Agent replay 状态时,不应使用纯内存模式。应切换到 PostgreSQL 加持久卷或外部对象存储。

公网客户门槛

如果把 Space 对外提供给客户使用,至少要满足以下门槛:

  • 先执行 npm run deploy:space,确保当前干净 git HEAD 已上传到固定 Space。
  • 再用真实浏览器打开 Space,确认页面能进入并完成一次真实的浏览器检查。
  • 仅有 npm run doctor:hf-space 的远端可达与 secret 检查,不足以证明客户可见上线。
  • APP_PASSWORD 已设置,网页不会裸露给匿名访问者。
  • AGENT_API_TOKEN 已设置,自动化调用不会回退到页面访问码哈希。
  • npm run doctor:hf-spaceremote-secrets 检查通过。
  • 共享链接明确保留访问码和有效期的默认控制,不把无访问码永久链接当成默认发布形态。
  • Space 重启丢失分享元数据和 Agent replay 的前提已被客户知晓。

Space Keepalive

本仓库提供 GitHub Actions 定时 keepalive,降低 CPU Basic 因长时间无访问进入休眠的概率:

  • 工作流文件:.github/workflows/hf-space-keepalive.yml
  • 默认频率:每 6 小时一次,可手动触发 workflow_dispatch
  • 默认目标:https://misonl-visual-journal.hf.space/api/auth-status
  • GitHub Actions 使用 Node 26,并在最多 4 次请求中按 5 秒、10 秒、20 秒退避重试;每次超时 30 秒。失败日志会记录 HTTP 状态、响应类型和下一次等待时间,不把失败伪装成成功,也不会输出上游响应正文。
  • 行为边界:只访问只读鉴权状态端点,不携带 APP_PASSWORDAGENT_API_TOKEN 或 OpenAI Key,不触发生图、不访问 Agent 生成接口。

如果 Space 地址变化,在 GitHub 仓库 Variables 中设置:

HF_SPACE_KEEPALIVE_URL=https://<user>-<space>.hf.space

本地手动验证:

HF_SPACE_KEEPALIVE_URL=https://<user>-<space>.hf.space \
HF_SPACE_KEEPALIVE_EXPECT_PASSWORD_REQUIRED=true \
HF_SPACE_KEEPALIVE_MAX_ATTEMPTS=4 \
HF_SPACE_KEEPALIVE_RETRY_DELAY_MS=5000 \
HF_SPACE_KEEPALIVE_RETRY_MAX_DELAY_MS=20000 \
npm run keepalive:hf-space

注意:keepalive 是 best-effort 机制,不能保证绕过 Hugging Face 平台维护、重启或政策限制。若需要平台级保证,应使用满足平台要求的硬件并设置永不休眠。

验证门禁

GitHub Actions 的 .github/workflows/ci.yml 会在 Pull Request、main 分支推送和手动触发时先核对锁文件安装脚本与 allowScripts 白名单、npm 的严格安装脚本能力,再以严格白名单模式安装依赖并核对直接依赖完整性,随后执行版本元数据检查、完整依赖审计、测试、源码 lint、脚本语法检查、生产构建、工作流 lint、Dockerfile 与基础 Compose 加 memory/PostgreSQL 覆盖配置检查。它还会构建和启动生产镜像后验证 /api/auth-status,并在独立 job 中运行真实 PostgreSQL 状态契约。

最小验证:

npm run install-scripts:check
npm run npm-install-policy:check
npm run dependencies:check
npm test
npm run lint
npm run lint:scripts
npm run build
npm run keepalive:hf-space
npm run smoke:hf-space-local
git diff --check

真实 Hugging Face gate:

  1. 提交代码后执行 npm run deploy:space,等待 Space 新 commit 进入 RUNNING
  2. 用真实浏览器打开 Space,确认页面可进入并至少完成一次页面检查。
  3. 电脑执行 GPT_IMAGE_AGENT_CONTRACT_CHECK=1 契约检查。
  4. 如有可用测试额度,再执行一次真实 Agent 生成。
  5. 重启 Space 后确认旧 Agent replay 和旧临时产物丢失符合预期。
  6. 如果未执行第 1 步和第 2 步,必须在门禁报告里明确标注残余外部门禁未验证。