docs: clarify sub2api multi-target public exposure (#968)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -5,7 +5,7 @@ description: UniDesk Sub2API 平台运维技能。用户提到 Sub2API、sub2api
|
||||
|
||||
# UniDesk Sub2API
|
||||
|
||||
UniDesk 在 k3s `platform-infra` namespace 运维 Sub2API。D601 是当前默认 active runtime,使用外置 PostgreSQL 和目标级 public exposure;G14 由同一 YAML/CLI 控制为 standby predeploy,默认缩容且不运行 sentinel、FRP 或 HTTPS egress proxy。日常操作统一使用 UniDesk CLI,不直接写 Kubernetes 资源或手工调用 Sub2API 管理 API。
|
||||
UniDesk 在 k3s `platform-infra` namespace 运维 Sub2API。D601 是当前默认 target,使用外置 PostgreSQL 和目标级 public exposure;D518 可作为独立 external-active target 与 D601 同时对外服务;G14 由同一 YAML/CLI 控制为 standby predeploy,默认缩容且不运行 sentinel、FRP 或 HTTPS egress proxy。日常操作统一使用 UniDesk CLI,不直接写 Kubernetes 资源或手工调用 Sub2API 管理 API。
|
||||
|
||||
**固定入口**: `cd /root/unidesk && bun scripts/cli.ts platform-infra sub2api ...`
|
||||
|
||||
@@ -33,11 +33,11 @@ bun scripts/cli.ts platform-infra sub2api codex-pool trace --request-id <request
|
||||
- 配置真相是 YAML:`config/platform-infra/sub2api.yaml` 和 `config/platform-infra/sub2api-codex-pool.yaml`。
|
||||
- 业务策略和具体数值只以 YAML 为准。已有字段的数值调整只改 YAML 并跑 `plan` / `sync --confirm` / `validate`;不要自动补代码硬编码、schema 硬范围、合同测试、单元测试或长期参考文档。配置校验只校验格式、类型、必填和可渲染性,不判断数值策略是否“合理”。
|
||||
- 本 skill 目录下若存在 `agents/*.yaml`,只作为 skill/agent 展示与调用元数据,不是 Sub2API 或 Codex pool 运行配置;不要在 skill 目录维护第二份账号、capacity、priority、endpoint 或 Secret 配置。
|
||||
- Runtime target 由 `config/platform-infra/sub2api.yaml` 声明;默认 `D601:k3s` 是 active target,`G14:k3s` 是 standby target。master server 只是控制端和消费者,不部署 Sub2API/PostgreSQL/Redis。
|
||||
- Standby target 不部署本地 PostgreSQL,不运行 sentinel、FRP 管理入口或 HTTPS egress proxy;只能预部署 namespace、NetworkPolicy、Service,以及 replicas=0 的 Sub2API/Redis Deployment。Redis 激活后也只允许 ephemeral cache。External-active target 仍不部署本地 PostgreSQL,必须直连 YAML 声明的外置 DB,使用本地 ephemeral Redis,并且只有在 YAML 启用时才运行 frpc、egress proxy 和目标级 sentinel。
|
||||
- Runtime target 由 `config/platform-infra/sub2api.yaml` 声明;默认 target 是 `D601:k3s`,`D518:k3s` 这类 external-active target 必须通过显式 `--target` 选择,`G14:k3s` 是 standby target。master server 只是控制端和消费者,不部署 Sub2API/PostgreSQL/Redis。
|
||||
- Standby target 不部署本地 PostgreSQL,不运行 sentinel、FRP 管理入口或 HTTPS egress proxy;只能预部署 namespace、NetworkPolicy、Service,以及 replicas=0 的 Sub2API/Redis Deployment。Redis 激活后也只允许 ephemeral cache。External-active target 仍不部署本地 PostgreSQL,必须直连 YAML 声明的外置 DB,使用本地 ephemeral Redis,并且只有在 YAML 启用时才运行 frpc、egress proxy 和目标级 sentinel;多个 external-active target 可以并存,不得把一个 target 的 public exposure 当作另一个 target 的替代或回退。
|
||||
- Secret、`~/.codex/config.toml*`、`~/.codex/auth.json*` 是运行时输入或本地状态,不提交。
|
||||
- 默认 `~/.codex/config.toml` 和 `~/.codex/auth.json` 只作为统一 Sub2API consumer 使用;`config.toml` 必须指向 YAML-selected active target 的 consumer URL,当前由 `codex-pool configure-local --confirm` 写入 D601 target-level public URL;`auth.json` 必须使用统一 pool API key。新增上游账号不得覆盖这两个默认文件,只能新增 `config.toml.<profile>` / `auth.json.<profile>` 并在 YAML 里声明。
|
||||
- 输出只能包含 Secret 路径、长度、preview/fingerprint;禁止打印完整 API key、admin password、JWT secret、TOTP key。
|
||||
- 输出只能包含 Secret 路径、key 名、presence、fingerprint 和 `valuesPrinted=false`;禁止打印完整 API key、admin password、JWT secret、TOTP key、base64 payload 或可复制的 preview。
|
||||
|
||||
## 部署与状态
|
||||
|
||||
@@ -140,7 +140,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool cleanup-probes --target D60
|
||||
|
||||
`sync --confirm` 会登录 Sub2API admin、创建/更新 group、创建/更新 YAML 中的 `unidesk-codex-*` accounts、创建/复用统一 API key Secret,并部署/更新哨兵资源;它不把既有 managed account 直接恢复为 `schedulable=true`。恢复只由哨兵在读取 Sub2API runtime `schedulable=false` 后触发 recovery probe,并在 marker 命中时执行。`sync` 默认不删除 YAML 中缺席的 managed account。只有明确退役上游时才使用 `sync --confirm --prune-removed` 删除缺席且 `extra.unidesk_managed=true` 的 `unidesk-codex-*` account。对 `manualAccounts.protected`,`sync` 只执行 YAML 显式允许的窄同步;当前允许项是从目标 `egressProxy` 创建/更新 Sub2API internal proxy 记录并绑定 `proxy_id`,以及把受保护手动账号加入当前 `pool.groupName`。它仍不接管该账号凭据、status、schedulable、priority/capacity/loadFactor 或哨兵状态。
|
||||
|
||||
`sentinel-image status|build` 管理哨兵 Python 运行环境镜像。镜像由 YAML 的 `sentinel.image` 基础镜像和 `sentinel.sdk.openaiPythonVersion` 派生,发布到目标 runtime 的本地 registry;`build --confirm` 会先检查 registry tag,存在则快速复用,不存在才在目标 host 构建并 push。CronJob 启动时只校验 SDK 版本,不在运行时 `pip install`。
|
||||
`sentinel-image status|build` 管理哨兵 Python 运行环境镜像。镜像由 YAML 的 `sentinel.image` 基础镜像和 `sentinel.sdk.openaiPythonVersion` 派生,发布到目标 runtime 的本地 registry;`build --confirm` 会先检查 registry tag,存在则快速复用,不存在才在目标 host 构建并 push。CronJob 启动时只校验 SDK 版本,不在运行时 `pip install`。目标是否启用哨兵以 `config/platform-infra/sub2api.yaml` 的 `sentinel.enabledOnTargets` 为准;未启用的 target 在 `sync`/`validate` 中应显示 `skipped-target-disabled`,不得要求镜像构建、CronJob、Secret 或 state ConfigMap 存在。
|
||||
|
||||
`sync --confirm` 同时会按 YAML 渲染账号级哨兵资源,并在 monitor 开启时先确保可复用哨兵镜像存在。当前目标是 `sentinel.monitor.enabled=true` + `sentinel.actions.enabled=true` 的 marker-only 自动冻结/恢复;不要手工 patch CronJob、Secret 或 Sub2API account。若 YAML 新增账号或修改 profile/base URL/API key fingerprint/upstream User-Agent/Responses WebSocket mode,sync 会从变更前 runtime state 写入 pending probe 记录并立即安排 sentinel probe,但不会把既有账号直接恢复为可调度;只有 sentinel 读取到 Sub2API runtime `schedulable=false` 后执行 recovery probe,且 marker 命中,才恢复 `schedulable=true`。sentinel 冻结/恢复只改 `schedulable=false|true`,不得顺手调用 Sub2API `recover-state` 清除请求路径临时不可调度或其他 runtime backoff。无关账号的既有成功/失败退避不能被重置。若 YAML 下调失败冻结最大窗口,sync 会把仍 active 的旧冻结状态迁移到当前最大窗口内并立即安排 recovery probe,但不会直接解冻。若怀疑某个账号被误判,先用 `codex-pool sentinel-probe --account <accountName> --confirm` 立即触发该账号测量;该命令从现有 CronJob 模板派生一次性 Job,复用同一份 Secret、ConfigMap、OpenAI SDK probe、token/cost 账本和冻结/恢复状态机。
|
||||
|
||||
@@ -203,15 +203,15 @@ bun scripts/cli.ts platform-infra sub2api codex-pool expose
|
||||
bun scripts/cli.ts platform-infra sub2api codex-pool expose --confirm
|
||||
```
|
||||
|
||||
- 由 YAML `publicExposure` 控制。Codex pool 默认公共端是 `publicBaseUrl`,master 本地消费端是 `masterBaseUrl`;D601 external-active 的目标级 public exposure 在 `config/platform-infra/sub2api.yaml` 中声明。
|
||||
- 由 YAML `publicExposure` 控制。Codex pool 默认公共端是 `publicBaseUrl`,master 本地消费端是 `masterBaseUrl`;external-active target 的目标级 public exposure 在 `config/platform-infra/sub2api.yaml` 中声明。
|
||||
- `expose --confirm` 只为 YAML 指定的 `remotePort` 补 master `frps` allow port,并在 G14 创建/更新 `sub2api-frpc`。
|
||||
- master Caddy site 也由 `publicExposure.masterCaddy` 渲染;`responseHeaderTimeoutSeconds` 必须足够覆盖 Codex `/responses/compact` 长请求,避免 Caddy 先返回 504 而 Sub2API 后台实际稍后成功。具体数值只改 `config/platform-infra/sub2api-codex-pool.yaml`,修改后跑 `codex-pool expose --confirm`,再核对 Caddyfile 中渲染出的 `response_header_timeout`。
|
||||
- master Caddy 的短窗口边缘重试由 `publicExposure.masterCaddy.edgeRetry` 渲染;用于吸收 FRP remotePort 短暂关闭、`connect: connection refused`、EOF 或 connection reset 这类请求尚未稳定到达 Sub2API 的 502。具体 retry 时长、间隔和 `retryMatch` 范围只写 YAML,修改后跑 `codex-pool expose --confirm`,再核对 Caddyfile 中渲染出的 `lb_try_duration`、`lb_try_interval` 和 `lb_retry_match`。不要手工 patch `/etc/caddy/Caddyfile`。
|
||||
- PK01 `/etc/caddy/Caddyfile` 是 Sub2API、LangBot、n8n、HWLAB 等多 YAML 来源共享的 edge artifact。Sub2API apply/expose 只能更新自己的 `# BEGIN unidesk managed sub2api` 块并保留其他 managed blocks;若 apply 输出显示 managed block 数异常,先停止 closeout,检查 PK01 Caddy 合并与 validation 结果,不要手工整文件覆盖。
|
||||
- PK01 `/etc/caddy/Caddyfile` 是 Sub2API、LangBot、n8n、HWLAB 等多 YAML 来源共享的 edge artifact。Sub2API apply/expose 只能更新自己的 managed block 并保留其他 blocks;同一 Sub2API 服务暴露多个 target 时,D601 保留既有 `# BEGIN unidesk managed sub2api`,非默认 target 必须使用 target-scoped owner(例如 `sub2api-d518`),避免 `api.pikapython.com` 和 `api2.pikapython.com` 互相覆盖。若 apply 输出显示 managed block 数异常,先停止 closeout,检查 PK01 Caddy 合并与 validation 结果,不要手工整文件覆盖。
|
||||
- 非幂等 POST 的 round-trip retry 必须收窄到 YAML `retryMatch` 声明的安全路径;普通 `/responses` 上游账号错误仍归 Sub2API failover / temp-unschedulable / sentinel 处理,不用 Caddy 重放整段推理请求来掩盖账号池问题。
|
||||
- 同一个 FRP TCP 入口同时暴露 OpenAI-compatible API 和 Sub2API 管理 UI `/login`。不要另开第二个管理端口,除非 YAML 明确声明新的暴露决策。
|
||||
- Sub2API Kubernetes Service 继续保持 ClusterIP。
|
||||
- D601 external-active 的公开路径是 `client -> PK01 Caddy -> PK01 frps remotePort -> D601 frpc -> Sub2API`,不经过 pikanode,也不经过 master server 反代。PK01 Caddy 下载必须使用 YAML `publicExposure.pk01.caddyDownloadProxyUrl` 指定的 proxy;如果 Caddy 下载慢,先确认 apply 输出里是 `downloadProxy.mode=curl-proxy`。`api.pikapython.com` 必须先解析到 YAML 声明的 PK01 公网地址,HTTPS 才能作为最终验证。
|
||||
- External-active target 的公开路径是 `client -> PK01 Caddy -> PK01 frps remotePort -> target frpc -> Sub2API`,不经过 pikanode,也不经过 master server 反代。PK01 Caddy 下载必须使用 YAML `publicExposure.pk01.caddyDownloadProxyUrl` 指定的 proxy;如果 Caddy 下载慢,先确认 apply 输出里是 `downloadProxy.mode=curl-proxy`。目标域名必须先解析到 YAML 声明的 PK01 公网地址,HTTPS 才能作为最终验证;D601 `api.pikapython.com` 与 D518 `api2.pikapython.com` 应分别验收。
|
||||
|
||||
## 配置 master Codex 消费端
|
||||
|
||||
@@ -239,6 +239,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool configure-local --confirm
|
||||
- `sub2api validate`:app、PostgreSQL、Redis、service proxy、`NetworkPolicy/allow-all` 和临时跨 Pod PostgreSQL/Redis 连通性检查通过。
|
||||
- `codex-pool validate`:统一 key 的 `GET /v1/models` 成功,并用 `localCodex.responsesSmokeModel` 跑一次小的 `POST /v1/responses` smoke;owner balance / owner concurrency 已满足 YAML 最小值,capacity、WebSocket v2、Sub2API 内置 temporary-unschedulable 开关/规则和 sentinel runtime 状态与 YAML 对齐;`validation.gatewayResponsesRecent` 汇总最近 6 小时普通 `/responses` 和 `/v1/responses` 的 failover、forward failure、最终 4xx/5xx、慢 final error 与 `context canceled` 证据,`validation.gatewayCompactRecent` 单独汇总 `/responses/compact` 证据。若当前 Responses smoke `ok=true` 但 recent 字段 `degraded=true`,先区分是历史窗口残留还是新的 request id 正在失败;长期判定见 `docs/reference/platform-infra.md`。
|
||||
- 若 `publicExposure.enabled=true`,确认 FRP path 可用;`expose --confirm` 会用未带 key 的 public `/v1/models` 401 作为网关可达性探针。
|
||||
- 多 target 同时启用 public exposure 时,必须分别验证每个 target 的 root、`/health`、未带 key `/v1/models` 401,以及各自 `codex-pool validate --target <id>`;一个域名可用不能替代另一个域名的验收。
|
||||
- 若目标声明了 `egressProxy.enabled=true`,确认 proxy Deployment/Service ready,Sub2API 和 sentinel env 与 YAML 对齐,并通过 YAML 声明的 health URL 完成代理出站探针。
|
||||
|
||||
如果要证明真实模型请求可用,使用最小 `/v1/responses` 或等价 Codex smoke。不要把 group-level `/v1/models` 成功解释成每个上游 account 都健康。
|
||||
@@ -253,6 +254,7 @@ bun scripts/cli.ts platform-infra sub2api codex-pool configure-local --confirm
|
||||
- 手动 OAuth/API-key 账号 WebUI account test 正常,但 PC Codex 客户端通过统一 key 访问 `/responses` 返回 503 且 trace 是 `account-select-failed` / `no available accounts`:按“受保护手动账号代理与分组绑定”小节确认 `manualAccounts.protected[].groupBinding.source: pool-group`,跑 `codex-pool sync --target D601 --confirm` 后用 `codex-pool validate --target D601 --full` 复测统一 key。
|
||||
- Sub2API 卡在 `wait-postgres` / `wait-redis` 或服务内大量 `context deadline exceeded`:先跑 `sub2api status` 看 `networkPolicy.ok`,再跑 `sub2api validate` 看 `postgresCrossPodPgIsReady` / `redisCrossPodPing`;缺失或异常时用 `sub2api apply --confirm` 恢复受控 `NetworkPolicy/allow-all`,不要保留手工 iptables bypass 作为长期修复。
|
||||
- pool key 401:跑 `codex-pool sync --confirm` 重建 Sub2API key 与 k3s Secret 绑定,再跑 `codex-pool validate`。
|
||||
- pool key、admin password 或 k8s Secret `.data` 被 stdout、日志、issue 或本地 transcript 打印时,按泄露处理:撤销对应 Sub2API key 或 token,删除/重建受影响的 target Secret,通过 `codex-pool sync --target <id> --confirm` 或相应 YAML sourceRef 重新下发,再用 fingerprint、presence 和 `valuesPrinted=false` 作为 closeout 证据;不要复述旧值或新值。
|
||||
- 运行中过去的验证探针残留:只用 `codex-pool cleanup-probes --confirm` 清理 `unidesk-probe-*` 临时资源;不要把真实 managed account 删除当作探针清理或可用性恢复。
|
||||
- FRP 不通:先看 `codex-pool expose --confirm` 输出的 `masterFrps`、`masterCaddy`、`sub2api-frpc` 和 public 401 probe;需要低层证据时只用 `trans G14:k3s` 做 bounded 查询。
|
||||
- D601 external-active 的 `api.pikapython.com` 不通:先区分 DNS/TLS/Caddy/FRP/Sub2API。DNS 未解析到 YAML 声明的 PK01 地址时,Caddy ACME 会失败,`https://api.pikapython.com` 不能算完成;可用 PK01 loopback FRP 端口和 PK01 公网 remotePort 证明 D601 FRP 数据路径,但最终仍要等 DNS 生效后重跑 HTTPS health、`/v1/models` 和 `/v1/responses`。
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
- Sub2API should stay ClusterIP-only by default. Do not add Ingress, NodePort, LoadBalancer, or broad FRP exposure unless a YAML-controlled public exposure decision exists.
|
||||
- Sub2API currently has no resource limits by design. Do not add CPU or memory limits unless a later explicit decision changes that policy and stores the new policy in YAML.
|
||||
- Master server is a consumer/control host, not the runtime location. Do not deploy Sub2API, PostgreSQL, Redis, or heavy validation loops on master server.
|
||||
- Sub2API active/standby placement is selected by YAML, not by ad hoc runtime patches. A standby target must render without a local PostgreSQL StatefulSet, keep the Sub2API app and local Redis cache scaled to zero, use only ephemeral Redis storage if Redis is later activated, and omit public FRP, HTTPS egress proxy, and account sentinel resources unless YAML explicitly promotes that target. An externally backed active target connects directly to the YAML-declared external PostgreSQL endpoint with `sslmode=require`, keeps durable app state outside the k3s node, and uses local Redis only as ephemeral cache. Promotion or failback must be applied by editing `config/platform-infra/sub2api.yaml` and running the same `platform-infra sub2api --target <id>` CLI path.
|
||||
- Sub2API active/standby placement is selected by YAML, not by ad hoc runtime patches. A standby target must render without a local PostgreSQL StatefulSet, keep the Sub2API app and local Redis cache scaled to zero, use only ephemeral Redis storage if Redis is later activated, and omit public FRP, HTTPS egress proxy, and account sentinel resources unless YAML explicitly promotes that target. An externally backed active target connects directly to the YAML-declared external PostgreSQL endpoint with `sslmode=require`, keeps durable app state outside the k3s node, and uses local Redis only as ephemeral cache. Multiple externally backed active targets may coexist when YAML declares distinct target ids, host routes, public URLs, FRP remote ports and Secret sources; target-scoped operations must use `--target <id>` and must not treat one target's URL or Secret as a fallback for another. Promotion or failback must be applied by editing `config/platform-infra/sub2api.yaml` and running the same `platform-infra sub2api --target <id>` CLI path.
|
||||
- External platform PostgreSQL endpoints for Sub2API are produced by the platform DB YAML and its `platform-db postgres` CLI. Cross-node Sub2API consumers connect directly to that endpoint; the master server is not a PostgreSQL data-plane relay. DNS aliases are optional when the exported `DATABASE_URL` uses a reachable IP with `sslmode=require`; current PK01-specific rules live in `docs/reference/pk01.md`.
|
||||
- Sub2API account sentinel, public exposure, and HTTPS egress proxy are target-scoped YAML decisions. The active target may run them when YAML enables them; the standby G14 target must stay deployed but inactive until YAML promotion. Do not create a second sentinel, FRP client, public management surface, or edge proxy by hand; enable or move those resources only through the target YAML and the `platform-infra sub2api` / `codex-pool --target` CLI paths.
|
||||
- Sub2API account sentinel, public exposure, and HTTPS egress proxy are target-scoped YAML decisions. The active target may run them when YAML enables them; the standby G14 target must stay deployed but inactive until YAML promotion. `sentinel.enabledOnTargets` is the authority for where Codex-pool sentinel image, CronJob, Secret and state resources are expected; disabled targets should report sentinel validation as skipped instead of failing on missing runtime sentinel objects. Do not create a second sentinel, FRP client, public management surface, or edge proxy by hand; enable or move those resources only through the target YAML and the `platform-infra sub2api` / `codex-pool --target` CLI paths.
|
||||
|
||||
## LangBot Deployment Boundary
|
||||
|
||||
@@ -161,7 +161,7 @@ The active Codex-pool request path follows the YAML-selected active target:
|
||||
4. Sub2API validates the unified key and resolves its `group_id`.
|
||||
5. Accounts listed in `profiles.entries` are bound to the same group via `group_ids`, so Sub2API dispatches through that group using its own account selection semantics.
|
||||
|
||||
For the current D601 externally backed active target, client traffic reaches PK01 Caddy, PK01 forwards to the YAML-declared FRP remote port, D601 `sub2api-frpc` connects directly to PK01 `frps`, and FRP forwards to `sub2api.platform-infra.svc.cluster.local:8080` on D601. This path does not pass through the master server or the pikanode reverse proxy. `api.pikapython.com` must resolve to the YAML-declared PK01 public address before Caddy can obtain or renew the public certificate; when DNS is missing, PK01 local FRP probes and public-IP remote-port probes may prove the edge path, but they are not a substitute for final `https://api.pikapython.com` validation.
|
||||
For an externally backed active target, client traffic reaches PK01 Caddy, PK01 forwards to that target's YAML-declared FRP remote port, the target's `sub2api-frpc` connects directly to PK01 `frps`, and FRP forwards to `sub2api.platform-infra.svc.cluster.local:8080` in the target namespace. This path does not pass through the master server or the pikanode reverse proxy. Each public hostname must resolve to the YAML-declared PK01 public address before Caddy can obtain or renew the public certificate; when DNS is missing, PK01 local FRP probes and public-IP remote-port probes may prove the edge path, but they are not a substitute for final HTTPS validation of that hostname. If D601 and D518 are both enabled, `api.pikapython.com` and `api2.pikapython.com` are separate entrypoints that must both remain valid.
|
||||
|
||||
When target-level `egressProxy.enabled=true`, the D601 target renders an in-cluster HTTP/mixed proxy client from the proxy source declared in YAML. The current mature external-egress shape is `sourceType: master-shadowsocks`: master Docker runs `shadowsocks-rust` from `config/platform-infra/sub2api-master-egress-proxy.compose.yaml`, while D601 runs `sing-box` to expose the ClusterIP proxy consumed by Sub2API and, when requested by YAML, the Codex account sentinel. A subscription-backed source is still just another YAML-declared source type; long-term prose must not duplicate the current endpoint, port, password, image tag, or health URL values from YAML/compose.
|
||||
|
||||
@@ -183,7 +183,7 @@ The public bridge has two separate failure classes. Sub2API upstream/account fai
|
||||
|
||||
PK01 `/etc/caddy/Caddyfile` is a shared edge artifact for multiple YAML owners, including platform-infra services and HWLAB node public exposure. Every platform-infra writer must use the shared managed-block helper in `scripts/src/pk01-caddy.ts` or the platform public-service wrapper around it. The helper preserves existing UniDesk managed blocks, updates only the caller's marker block, validates the merged Caddyfile before install, and reloads Caddy only after validation succeeds.
|
||||
|
||||
Do not render and install a whole PK01 Caddyfile from a single service YAML. Sub2API, LangBot, n8n, HWLAB and future public services must coexist by distinct `# BEGIN unidesk managed <owner>` blocks. A public exposure closeout should verify the service's own public URL and, when the operation touched PK01 Caddy, confirm that unrelated managed blocks are still present or that the apply output reports they were preserved.
|
||||
Do not render and install a whole PK01 Caddyfile from a single service YAML. Sub2API, LangBot, n8n, HWLAB and future public services must coexist by distinct `# BEGIN unidesk managed <owner>` blocks. When the same service exposes multiple public targets at once, the Caddy owner must be target-scoped unless an existing legacy owner is intentionally preserved for backward compatibility; for Sub2API, D601 keeps the legacy `sub2api` block and non-default targets use owners such as `sub2api-d518`. A public exposure closeout should verify the service's own public URL and, when the operation touched PK01 Caddy, confirm that unrelated managed blocks are still present or that the apply output reports they were preserved.
|
||||
|
||||
## Availability And Probes
|
||||
|
||||
@@ -204,7 +204,7 @@ When an automatic availability probe is added, it should be YAML-controlled and
|
||||
3. A tiny `POST /v1/responses` call through the same consumer URL for true OpenAI-compatible request validation.
|
||||
4. Optional per-upstream account probes if Sub2API exposes a safe account selection or admin-health mechanism; otherwise document that group-level success does not prove every upstream account is healthy.
|
||||
|
||||
For D601 public exposure, the equivalent probe set must use the target URL from `config/platform-infra/sub2api.yaml`, include the PK01 Caddy/FRP edge, and require `api.pikapython.com` DNS to resolve to the YAML-declared address before treating HTTPS as validated.
|
||||
For Sub2API public exposure, the equivalent probe set must use each target URL from `config/platform-infra/sub2api.yaml`, include the PK01 Caddy/FRP edge, and require the target hostname to resolve to the YAML-declared address before treating HTTPS as validated. Multi-target closeout must validate each public hostname independently, including root or management UI reachability, `/health`, unauthenticated `/v1/models` returning the expected auth failure, and a target-scoped keyed `codex-pool validate --target <id>` smoke.
|
||||
|
||||
Until continuous probing exists, closeout comments must state that validation was on-demand and include the exact CLI/API entrypoints used.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user