@broberg/部署核心
Broberg.ai舰队共享部署执行层. 它包含三件事:
| 编 | 它会做什么 |
|---|---|
飞行生活 (单位:千美元)flyLiveDeploy, (中文(简体) ), syncContent, (中文(简体) ), diffManifests, (...) (中文(简体) ) | HMAC在Fly应用程序上签名的增量内容同步,加上了后续的一次性构建. |
FlyClient (自0.4.0起) | Fly.io API:在机器REST API之上的应用和机器,GraphQL称机队使用. |
createDeployEventBus (自0.1.0起) | 进程内部署- 活动总线: Webhook 接收器发布, SSE 端点订阅, 每 orgId:siteId。 。 。 . |
没错 没有 包含 Cloudflare Pages 或 GitHub Pages 供应商(计划用 F033.2) .
部署活动公交车(0.0.0,F033.3)
import { createDeployEventBus } from "@broberg/deploy-core";
const bus = createDeployEventBus({
dispatch: (e) => sendPush(e), // optional: only for "built" / "errored"
onError: (err, where) => log.warn(where, err), // default console.warn
});
const off = bus.subscribe(orgId, siteId, (e) => sse.send(e));
bus.publish({ type: "page-build", orgId, siteId, status: "built", url, ts: new Date().toISOString() });
bus.listenerCount(orgId, siteId);
- 每个应用程序一班车,出自工厂——从不使用模块级地图,因此一个过程中的两辆公交车从不相听.
- 没有
originator字段. F033.4计划用于Upmetrics的中继器,并关闭了30/10: Upmerics从项目本身引出发件人. - 向一个网站出版,没人听 是没有的. 推钩仍然会为终端事件起火,因为推到没有标签的用户.
- 丢弃的听众或失败的推力通过
onError,从不向出版的网页胡克扔出,也从不默默地吞下(cms的原作有空接取来). - 单一过程. 一个应用程序的若干实例需要Redis pub/sub;超出范围.
Fly Live:服务器固定到达已运行的应用程序(0.8.0,F033.18)
flyLiveDeploy 同步 Content 到一个响应的应用程序 /_icd/health;它从未替换过容器内的服务器代码. 因此,服务器修补(0.7.0's Cache-Control)只到达了碰巧被重新提供的应用程序. 现在服务器报告 FLY_LIVE_SERVER_VERSION ——自身代码和Dockerfile的散列,所以服务器随时会改变——和 flyLiveDeploy 当一个活应用程序报告一个不同的版本时, 选择下行路径 。 结果显示: { mode: "infra", reason: "server version 1.0.0 ≠ 82b3…" }。 。 。 .
升级后的首个部署是 每一个应用程序的后期部署 (每个运行的服务器都报告旧"1.0.0"). 之后,部署再次是内容同步. chooseDeployMode(health, expected, forceInfra) 如果您要决定自己,则导出.
飞行密度
import { FlyClient } from "@broberg/deploy-core";
const fly = new FlyClient(); // token from FLY_API_TOKEN, or { token }
await fly.listApps("personal"); // one org
await fly.listAllApps(); // every org the token sees, all pages
const [m] = await fly.listMachines("my-app");
await fly.updateMachine("my-app", m.id, { // resize: pass the WHOLE config
...m.config,
guest: { ...m.config.guest!, memory_mb: 512 },
});
await fly.waitForState("my-app", m.id, "started", 120);
const { state, exitCode } = await fly.waitForExit("my-app", jobId);
const { entries, nextToken } = await fly.getMachineLogs("my-app", m.id); // since 0.6.0
await fly.getMachineLogs("my-app", m.id, { nextToken }); // only newer lines — poll this to tail
await fly.listVolumes("my-app"); // destroyed ones included — filter on state
await fly.deleteVolume("my-app", "vol_123"); // 0.11.0 — Fly refuses an attached volume (FlyApiError). A lost answer + retry can throw 404 although it IS gone: re-read listVolumes before saying "not deleted"
await fly.updateVolume("my-app", "vol_123", { snapshot_retention: 14, auto_backup_enabled: true }); // 0.11.0 — only the fields you give are sent
await fly.listIps("my-app"); // 0.9.0 — [{ ip, shared, region, serviceName, createdAt }]; a failure throws, never []
await fly.promQuery("personal", 'sum(fly_instance_memory_mem_available{app="my-app"})');
还: getApp, (中文(简体) ), createApp, (中文(简体) ), deleteApp, (中文(简体) ), getMachine, (中文(简体) ), createMachine, (中文(简体) ),
startMachine, (中文(简体) ), stopMachine, (中文(简体) ), destroyMachine, (中文(简体) ), listOrgs, (中文(简体) ), setSecrets, (中文(简体) ),
allocateIp。 。 。 .
手卷客户端通常不会
每一份都是用消费者自己的副本或活的API来衡量的 (24 September 2026)——每个测试如果被取消则会红:
- 仅在第二次尝试中重试成功之处 : 网络错误, 408, 429,
5xx. A 401, 403, 404或422一并投掷
FlyApiError { status, method, path }. (一份重审了一切的复制品 将错误的符号变成了30分钟) 投票结果。 ) waitForExit报告exitCode: null当飞行记录无. 没有 这叫成功,你决定.waitForExit扔出一个404的机器 它从未见过 (自0.5.0起) 飞 回答404"机器没有找到" 无论是错误的ID 和错误的Token,所以 a 第一次民意调查的404没有被"破坏". 只有一台机器在前面看到过 随即消失的民意调查(自发)报告为:destroyed。 。 。 .promQuery隐藏 Fly 的 Prometheus 认证陷阱 (自0.5.0起) 飞来飞去 普罗米修斯回答401Bearer和想要的,我们FlyV1 <token>; 机器 API 带熊儿去 HTTP 200 带status: "error"掷出.waitForState将Fly的408读作"还没有". 飞来飞去/wait回答 408 当 它本身的超时 ; 客户端一直询问直到您超时为止, 然后掷出FlyTimeoutError。 。 。 .- GraphQL HTTP 200 不成功 . 飞去回答200个坏信条
机构错误; 客户端丢出一个
FlyApiError状态401. listAllApps完成或丢出. 它走遍每一页,检查 倒计时 Fly自己的totalCount。片面列表从来就不是整体 第一——当呼叫者删除其中缺失的内容时,这很重要.getMachineLogs使用 Fly 的日志 API,而不是明显的地址 (自0.6.0起).api.machines.dev/v1/apps/<app>/machines/<id>/logs答复404——计量 2026年9月29日 — 吞入错误的手卷传粉器显示为空日志 永远 真正的终点是api.fly.io/api/v1/apps/<app>/logs?instance=<id>像普罗米修斯一样FlyV1 <token>200个没有data数组抛出.- 符号从未在错误中出现 留言或身体.
对真实的飞行API进行验证
test/live/fly-api.live.ts 运行针对现有应用程序的只读运行(对比
与 flyctl machines list 编号 : flyctl volumes list附加时 promQuery 编辑
永远看不到的机器 404; FLY_LIVE_READ_ONLY=1 ——创建应用程序,创建
机器, 调整大小并读回, 停, 一个退出 3, 销毁, 删除的过程
app——在一个被丢弃的应用程序中,它总是删除. 手动运行;不是
vitest run。 。 。 .