AI App 安装与服务部署进度 API
本文说明 AI App 手动安装、设备侧服务部署、流式进度,以及按 serviceId 查询最近部署状态的接口。
如需联调测试流程,可参考项目仓库中的部署进度测试文档。
1. 基础约定
- AI Pod 对外域名:
https://<subdomain>.<box-domain> subdomain从应用的lzc-manifest.yml中读取,当前默认是aibox-domain优先通过lzc-cli box default获取;拿不到时默认使用13gxg.heiyu.space
平台侧接口基准路径:
https://<subdomain>.<box-domain>/backend/aiappshttps://<subdomain>.<box-domain>/backend/services
设备侧接口基准路径:
http://<device-ip>:<device-port>/v1/service
2. AI App 手动安装
2.1 POST /backend/aiapps/install/stream
用途:
- 上传一个 AI App ZIP
- 完成注册
- 如果包内带
pkg/ai-pod-service/docker-compose.yml,继续触发设备部署 - 通过 SSE 返回安装进度
请求:
- Method:
POST - Content-Type:
multipart/form-data - 必填字段:
file
返回:
- Content-Type:
text/event-stream - 事件名:
progress
事件结构:
json
{
"stage": "pulling",
"status": "downloading",
"progress": 37,
"message": "registry.lazycat.cloud/demo/app:latest: Downloading",
"pkgId": "demo-app",
"serviceId": "demo-app",
"currentImage": "registry.lazycat.cloud/demo/app:latest",
"currentLayer": "sha256:abcd",
"current": 5242880,
"total": 10485760,
"error": ""
}说明:
- 本地包处理阶段仍会发送
upload_saved、unzipping、validating、registering等状态消息。 - 这些阶段的
progress固定为0,不计入安装进度条。 - 真正推进安装进度的是服务部署阶段:
pulling:0-80starting:85waiting:95completed:100failed: 保持失败前进度
- 如果 AI App 没有可部署服务,则直接返回:
stage=completedprogress=100message=installed without deployable service
典型返回:
text
event:progress
data:{"stage":"registering","progress":0,"message":"registering ai app","pkgId":"demo-app"}
event:progress
data:{"stage":"pulling","status":"downloading","progress":31,"message":"registry.lazycat.cloud/demo/app:latest: Downloading","pkgId":"demo-app","serviceId":"demo-app","currentImage":"registry.lazycat.cloud/demo/app:latest","currentLayer":"sha256:abcd","current":5242880,"total":10485760}
event:progress
data:{"stage":"starting","status":"starting","progress":85,"message":"starting service","pkgId":"demo-app","serviceId":"demo-app"}
event:progress
data:{"stage":"waiting","status":"waiting","progress":95,"message":"waiting for service health","pkgId":"demo-app","serviceId":"demo-app"}
event:progress
data:{"stage":"completed","status":"complete","progress":100,"message":"service deployed","pkgId":"demo-app","serviceId":"demo-app"}失败示例:
text
event:progress
data:{"stage":"failed","status":"error","progress":42,"message":"pull images failed","pkgId":"demo-app","serviceId":"demo-app","error":"pull access denied"}2.2 DELETE /backend/aiapps/apps/:pkgId
用途:
- 删除手动安装的 AI App
- 同步删除对应服务目录、缓存目录和镜像
返回:
json
{"removed":true,"pkgId":"demo-app"}2.3 GET /backend/aiapps/apps
用途:
- 查看当前 AI App 列表
2.4 GET /backend/aiapps/installed/:pkgId
用途:
- 查看指定
pkgId是否已经注册到 AI App store
返回:
json
{"installed":true}3. 平台侧服务接口
3.1 GET /backend/services/progress?serialNumber=<sn>&serviceId=<serviceId>
用途:
- 查询某台设备上指定服务最近一次部署进度
- 适用于自动触发部署场景,或手动安装过程中断线后恢复查看
返回结构:
json
{
"serviceId": "demo-app",
"stage": "pulling",
"status": "extracting",
"progress": 56,
"message": "registry.lazycat.cloud/demo/app:latest: Extracting",
"currentImage": "registry.lazycat.cloud/demo/app:latest",
"currentLayer": "sha256:abcd",
"current": 7340032,
"total": 10485760,
"startedAt": 1742880000,
"updatedAt": 1742880012,
"finishedAt": 0,
"error": ""
}空闲态返回:
json
{
"serviceId": "demo-app",
"stage": "idle",
"progress": 0,
"message": "deployment not started"
}3.2 现有平台侧接口
GET /backend/services/list?serialNumber=<sn>GET /backend/services/start?serialNumber=<sn>&serviceId=<serviceId>GET /backend/services/stop?serialNumber=<sn>&serviceId=<serviceId>GET /backend/services/delete?serialNumber=<sn>&serviceId=<serviceId>GET /backend/services/log?serialNumber=<sn>&serviceId=<serviceId>
说明:
start是同步触发,不返回流式进度- 自动触发部署和
start都会持续更新serviceId对应的最近部署状态 - 若需要实时进度,优先使用 AI App 安装流或设备侧
/service/start/stream
4. 设备侧服务接口
4.1 POST /v1/service/start
用途:
- 触发一次同步部署
- 内部仍会更新最近部署状态
请求字段:
file: service zipserviceIddirOverWrite:true|falseforceRecreate:true|falseextraEnv[KEY]=VALUE: 可选
4.2 POST /v1/service/start/stream
用途:
- 触发一次流式部署
- 与
/v1/service/start使用同一套底层部署逻辑 - 只是额外把进度通过 SSE 返回
返回:
- Content-Type:
text/event-stream - 事件名:
progress - 数据结构与
backend.ServiceDeployStatus一致
4.3 GET /v1/service/progress?serviceId=<serviceId>
用途:
- 查询该服务最近一次部署状态
4.4 GET /v1/service/log?serviceId=<serviceId>
用途:
- 持续查看服务日志
4.5 GET /v1/service/installed
用途:
- 查看设备上当前已安装服务及
docker-compose.yml摘要信息
5. 部署进度语义
统一状态字段:
stage: 粗粒度阶段status: 细粒度状态progress: 0-100message: 人类可读消息
当前阶段定义:
| stage | progress | 含义 |
|---|---|---|
idle | 0 | 当前没有部署记录 |
prepare | 0 | 开始部署,准备目录、解压、写 .env |
pulling | 0-80 | 拉取 compose 镜像 |
starting | 85 | 执行 docker-compose up -d --wait |
waiting | 95 | 容器已拉起,等待健康检查或 --wait 完成 |
completed | 100 | 部署成功 |
failed | 保持当前值 | 部署失败,错误见 error |
pulling.status 目前可能出现:
preparepreparingwaitingdownloadingdownload_completeextractingverifyingalready_existscomplete
说明:
pulling的百分比来自 Docker EngineImagePull的结构化字节进度,不再依赖docker-compose pullPTY 文本。- 多镜像场景下,按镜像平均权重汇总成整体
0-80进度。 starting和waiting目前是阶段型进度,不是容器级精确百分比。- 系统只保留每个
serviceId最近一次部署状态。
6. 调用示例
6.1 手动安装 AI App 并查看流式进度
bash
curl --no-buffer \
-F "file=@./demo-app.zip" \
"https://ai.13gxg.heiyu.space/backend/aiapps/install/stream"6.2 查询某个服务最近部署状态
bash
curl \
"https://ai.13gxg.heiyu.space/backend/services/progress?serialNumber=<sn>&serviceId=demo-app"6.3 直接调用设备侧流式部署接口
bash
curl --no-buffer \
-F "file=@./demo-app-service.zip" \
-F "serviceId=demo-app" \
-F "dirOverWrite=true" \
"http://<device-ip>:<device-port>/v1/service/start/stream"6.4 直接调用设备侧部署状态查询接口
bash
curl "http://<device-ip>:<device-port>/v1/service/progress?serviceId=demo-app"7. ZIP 结构要求
AI App ZIP 结构:
text
demo-app/
└── pkg/
├── manifest.yml
├── icon.png
├── extension.zip
└── ai-pod-service/
└── docker-compose.yml设备侧 service zip 结构:
text
demo-app/
├── docker-compose.yml
└── ...AI App 规则:
- ZIP 内必须存在且只能解析出一份
pkg/manifest.yml - 如果要参与服务部署,必须存在
pkg/ai-pod-service/docker-compose.yml
8. 兼容性说明
- 自动触发部署、手动安装流式部署、平台侧
start接口,共用同一套底层部署逻辑和同一份状态仓库。 - 手动安装时,AI App SSE 直接透传设备侧部署进度。
- 自动触发部署时,不返回 SSE;调用方应通过
serviceId查询最近部署状态。