Skip to main content

fnos-publish

飞牛 App 发布助手 —— 交互式勾选,把任意飞牛项目打成 .fpk 并推镜像到 Docker Hub,支持国内 fnOS 与海外 Fygo OS 双平台。当用户说「发布飞牛 app」「打包上架」「打飞牛包」「出 fpk」「推镜像到 docker」「上架应用中心」「发海外版/Fygo」「fnos publish」「打包并上传 docker」时使用。镜像在飞牛 NAS 上原生构建(x86_64),国内直连 Docker Hub 被墙时自动走本地代理 + crane 推送。

Zur Installation springen

Quellinformationen

Repository
go7th/fnos-publish
Letzte Quellaktivität
8. Juli 2026 um 08:02
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
fnos-publish
description
飞牛 App 发布助手 —— 交互式勾选,把任意飞牛项目打成 .fpk 并推镜像到 Docker Hub,支持国内 fnOS 与海外 Fygo OS 双平台。当用户说「发布飞牛 app」「打包上架」「打飞牛包」「出 fpk」「推镜像到 docker」「上架应用中心」「发海外版/Fygo」「fnos publish」「打包并上传 docker」时使用。镜像在飞牛 NAS 上原生构建(x86_64),国内直连 Docker Hub 被墙时自动走本地代理 + crane 推送。
# 飞牛 App 发布助手 把任意**飞牛项目**(含 `fnos/manifest` + `Dockerfile` + `fnos/app/docker/docker-compose.yaml`)打包并发布。脚本 `fnos_publish.sh` 按 `manifest` 的 `appname` 自省,同一份逻辑通用于所有同构项目。**交互式勾选**:先用 AskUserQuestion 让用户选清楚,再执行。 脚本路径:`~/.claude/skills/fnos-publish/fnos_publish.sh` ## 交互流程(务必先问清再动手) 用 **AskUserQuestion** 依次收集(能自动确定的就别问): 1. **选 App**(若当前 cwd 已是飞牛项目则默认它;否则在你放飞牛项目的目录下扫描候选,可设 `FNOS_PROJECTS_DIR`) ```bash for d in "${FNOS_PROJECTS_DIR:-.}"/*/; do [ -f "$d/fnos/manifest" ] && \ printf "%s\t%s\n" "$(basename "$d")" "$(grep -E '^display_name' "$d/fnos/manifest" | awk -F= '{print $2}' | xargs)"; done ``` 2. **目标平台**(multiSelect):国内 fnOS / 海外 Fygo OS →`--target inland|oversea|both` 3. **动作**(multiSelect): - 在 NAS 构建镜像(默认开;不勾=`--no-build` 复用已有镜像 tar) - 推镜像到 Docker Hub →`--push` - 国内额外出离线版 →`--offline` - 上传 .fpk 到 NAS →`--upload` 4. 若选了 `--push` 且 `docker` 未登录 Docker Hub → 让用户提供 access token,先非交互登录。 5. 若选了 **海外** 且项目没有 `fnos/manifest.oversea` → 提示是否现在生成英文版 manifest(见下)。 确认后进入项目目录执行,例如: ```bash cd /path/to/your/fnos-project && \ DOCKER_USER=your-dockerhub-user NAS_HOST=your-nas-ip NAS_PASS='****' \ bash ~/.claude/skills/fnos-publish/fnos_publish.sh --target both --push --offline ``` ## 产物(`dist/`) | target | 文件 | 说明 | |--------|------|------| | inland | `<app>-<ver>.fpk` | 国内默认版,image 改写成 `<user>/<app>:<ver>`,应用中心自动从 Docker Hub 拉 | | inland+`--offline` | `<app>-<ver>-offline.fpk` + `<app>-image-<ver>.tar.gz` | 离线版,`pull_policy:never` + 本地 load | | oversea | `<app>-<ver>-oversea.fpk` | 海外版,image 同样走 Docker Hub(海外无墙,天然合适) | | — | `安装说明-*.txt` / `发布说明-海外.txt` | 给用户/审核的说明 | ## 国内 fnOS vs 海外 Fygo OS 差异 | 维度 | 国内 fnOS (`developer.fnnas.com`) | 海外 Fygo OS (`developer.fygonas.com`) | |------|-----------------------------------|----------------------------------------| | 打包工具 | `fnpack build` | `fygopack create` / `fygopack pack` | | 上架 | appcenter-cli / 官方流程 | **邮件提交 `app-review@fygo.io`** | | manifest | `arch=x86_64`、`service_port`… | 示例有 `platform`、`maintainer_url`、`ctl_stop`;建议英文 `display_name`/`desc` | | 语言 | 中文 | en / ja / zh(海外优先英文) | | 镜像仓库 | 国内走阿里云 mirror | Docker Hub(对海外用户无墙,直接用 `<user>/<app>`) | > 本脚本对两端都用「手工 tar 复刻官方 .fpk 结构」出包,`fygopack` 的完整 manifest 字段规范官方文档未给全。若要官方校验,在装有 `fygopack` 的机器上跑一次 `fygopack pack` 核对字段后再提交审核。 ## 🌐 海外 i18n / 语言转化(四层,缺一层就会露中文) 海外包不是「换个英文 manifest」就完事——UI、桌面入口、说明都要英文。脚本已自动处理能自动的部分,其余是**应用侧前置条件**,`--target oversea|both` 时会打印缺失清单: | 层 | 素材 | 谁负责 | |----|------|--------| | 1. 应用信息 | `fnos/manifest.oversea`:英文 `display_name`/`desc`(脚本优先用它) | 你提供 | | 2. 桌面入口 | `fnos/app/ui/config.oversea`:桌面图标 `title` 改英文(脚本自动覆盖进包) | 你提供 | | 3. 前端 UI | 应用必须已接 **i18n**(Umi `locale` / react-i18next)并有 `en-US` 词条 | 应用代码 | | 4. 默认语言 | 脚本自动在海外 compose 的 `environment` 注入 `APP_LOCALE=en-US` + `LANG=en_US.UTF-8` | **脚本自动** | **约定**:前端/后端启动时读环境变量 `APP_LOCALE`(缺省 `zh-CN`),据此选默认语言。这样**同一个 Docker 镜像**既能国内跑中文、海外跑英文,不必构建两份镜像。给各飞牛 app 统一加这段即可: ```ts // 前端(Umi):入口处 const locale = (import.meta as any)?.env?.APP_LOCALE || (window as any).APP_LOCALE || 'zh-CN'; // 由容器注入,海外=en-US setLocale(locale, false); ``` ```python # 后端(FastAPI):读同名变量决定返回文案语言 LOCALE = os.getenv("APP_LOCALE", "zh-CN") ``` > 若某 app 尚未接 i18n,海外包里 UI 仍是中文——这层打包改不了,得先在应用里补 i18n + `en-US` 词条。脚本会明确告警,别忽略。 ### 生成海外素材 - `fnos/manifest.oversea`:从 `fnos/manifest` 复制,`display_name`/`desc` 改英文,其余保留。 - `fnos/app/ui/config.oversea`:从 `fnos/app/ui/config` 复制,`title` 改英文。 - 缺失时脚本用中文素材兜底并告警,Fygo 审核前务必补齐。 ## ⚠️ 陷阱 1:本地 tag vs registry 引用(别手改源 compose) 源 `docker-compose.yaml` 里 `image: <app>:latest` 是**本地构建 tag**。脚本已自动分流:registry 版 sed 改写成 `<user>/<app>:<ver>`,离线版加 `pull_policy: never`。**不要手动改源 compose 的 image 行**。打完可校验: ```bash mkdir -p /tmp/c && tar xzf dist/<app>-<ver>.fpk -C /tmp/c app.tgz && \ tar xzf /tmp/c/app.tgz -C /tmp/c docker/docker-compose.yaml && grep -E 'image:|pull_policy' /tmp/c/docker/docker-compose.yaml # registry 版应是 <user>/<app>:<ver>;离线版应是 <app>:latest + pull_policy: never ``` ## ⚠️ 陷阱 2:国内直连 Docker Hub 上传被定向阻断(脚本已自动绕过) `docker push` 由 daemon 发起,国内直连 `registry-1.docker.io` 时控制面能过,一传大 blob(如 opencv/numpy 层 ~200MB)就在 `Head .../blobs/sha256:...` 处 `EOF`——定向阻断,重试无效;且 Docker Desktop 的 daemon 在 VM 里吃不到宿主 `127.0.0.1` 代理。 **脚本的 `--push` 已内置解法**:探测本地代理(Clash Verge 常见 `7897`,Clash `7890`),命中则用 **`crane`(纯 CLI,直吃 `HTTPS_PROXY`,读 `~/.docker/config.json` 登录态)**经代理直推;未探测到代理才退回 `docker push`。 前置:先登录(token 从 Docker Hub → Account Settings → Personal access tokens,给 Read/Write): ```bash echo '<dckr_pat_...>' | docker login -u <your-dockerhub-user> --password-stdin ``` 可用 `PROXY=http://127.0.0.1:<port>` 显式指定代理端口。 ## 推送后必做 1. 首次推某仓库后,到 Docker Hub 把 `<user>/<app>` 设 **Public**(否则别人无登录拉不到)。 验证:`DOCKER_CONFIG=$(mktemp -d) HTTPS_PROXY=http://127.0.0.1:7897 crane manifest <user>/<app>:<ver>` 能拿到=Public。 2. 清理:解压出的 `dist/<app>-image-<ver>.tar`(~几百 MB)验证后删,保留 `.tar.gz`。 3. 安全:docker access token 用完可到 Docker Hub 吊销重建;`dist/` 别提交进 git。 ## 版本号 单一事实源:`fnos/manifest` 的 `version`(脚本读它当 `<ver>`),与后端 `main.py` 的 `version="…"` 保持一致。升版本先改这两处再打包。 ## 决策提示(给 Claude) - 只改前端/`fnos/` 配置、没动后端 → 勾「复用镜像」(`--no-build`)。 - 改了后端/依赖/Dockerfile → 必须重新构建(默认)。 - 「让别人也能装」→ 必须 `--push` + 仓库设 Public,否则只能发离线版两文件。 - 缺 `NAS_PASS` 会卡在 SSH 密码交互 → 先问用户要密码或让其 `export NAS_PASS`。 - 海外提交前确认英文 manifest 与 Public 仓库就绪。
Auf GitHub ansehen