自定义镜像模板
模板定义沙箱启动时使用的镜像、资源、环境变量、启动行为、就绪检查和存储挂载。
首次接入优先使用官方模板。重复安装和启动逻辑稳定后,再构建自定义模板。
什么时候构建模板
Section titled “什么时候构建模板”以下情况适合构建自定义模板:
- 依赖只安装一次,而不是每次沙箱启动都安装
- 将源码复制进可复用镜像
- 固定 OS 包和语言包版本
- 定义
startCmd和readyCmd - 通过模板策略挂载持久存储路径
- 通过
stable或prod等标签推广已验证构建
官方模板选择
Section titled “官方模板选择”| 目标 | 建议起点 |
|---|---|
| Shell 命令和文件操作 | base |
| 代码解释器和数据分析 | code-interpreter |
| Node 前端或 API 服务 | node 或 web-frontend |
| Python 服务或脚本 | python |
| 浏览器自动化 | browser |
| 持久工作区 | nfs、cloud、block 或自定义 tpl-... |
| 生产可复现 | 具体 tpl-... |
SDK 构建示例
Section titled “SDK 构建示例”import { Sandbox, Template, waitForPort } from "@seacloudai/sandbox";
const built = await Template.build( new Template() .fromNodeImage("20-alpine") .copy("./my-app", "/app", { forceUpload: true }) .runCmd("cd /app && npm install") .runCmd("cd /app && npm run build") .setStartCmd("cd /app && npm start", waitForPort(3000)), "my-app:v1", { wait: true },);
const app = await Sandbox.create(built.templateId, { waitReady: true });console.log(app.getHost(3000));公开构建流程
Section titled “公开构建流程”- 通过
POST /api/v1/templates创建模板元数据。 - 将本地源码打包为
.tgz。 - 通过构建上下文握手上传归档文件。
- 调用
/api/v1/templates/:templateID/builds/:buildID启动构建。 - 轮询状态直到
ready。 - 使用返回的
templateID创建沙箱。
构建上下文上传
Section titled “构建上下文上传”公开构建流程会按 hash 对本地源码归档去重。
GET /api/v1/templates/:id/files/:hashX-API-Key: <token>响应可能包含签名上传 URL 和 maxContextBytes。
{ "present": false, "url": "https://storage.googleapis.com/...", "maxContextBytes": 104857600}默认单个归档上限为 100MiB。上传前应排除 .git、node_modules、dist、.next、缓存目录和生成产物。
| 状态 | 含义 |
|---|---|
uploaded | 等待引用的构建上下文上传。 |
waiting | 构建已接收并排队。 |
building | 构建任务正在运行。 |
ready | 构建完成,模板镜像可用。 |
error | 构建失败。 |
构建状态响应可能包含 timeline、steps、logs、logEntries 和 reason。进度 UI 优先使用 timeline 与 steps,详情再展示日志。
标签与稳定引用
Section titled “标签与稳定引用”标签是构建版本指针。my-template:stable 会解析到 stable 标签绑定的构建镜像,而不一定是模板当前最新的 currentBuildId。
POST /api/v1/templates/tagsX-API-Key: <token>Content-Type: application/json{ "target": "my-template:v1", "tags": ["stable", "prod"]}Dockerfile 映射
Section titled “Dockerfile 映射”公开构建接口当前接收结构化构建步骤,而不是原始 Dockerfile 文本。
| Dockerfile 指令 | 构建 payload |
|---|---|
FROM node:20 | fromImage: "node:20" 或官方基础模板引用 |
WORKDIR /app | WORKDIR step |
COPY . /app | 带 filesHash 的 COPY step |
RUN npm install | RUN step |
ENV NODE_ENV=production | ENV step |
CMD npm start | startCmd |
| Mode | 含义 |
|---|---|
managed | nano-executor 运行时 API 可在运行时端口访问,通常是 9000。 |
plain | 镜像自己拥有前台应用进程;nano-daemon 仍可提供探针和心跳。 |
workdir 控制默认进程和文件根目录,但不创建持久存储。存储拓扑来自模板 volumeMounts。
startCmd 与 readyCmd
Section titled “startCmd 与 readyCmd”使用 startCmd 为未来从该模板创建的沙箱启动长运行应用进程。使用 readyCmd 判断沙箱是否已经可用。
好的就绪检查应该是本地、有限时长,并且和用户会打开的端口一致:
wget -q -O- http://127.0.0.1:3000/ >/dev/null避免只证明进程存在、但不能证明应用可用的检查:
ps aux | grep nodestartCmd 和 readyCmd 使用 shell 语义。镜像应包含 /bin/sh,或命令应按该镜像可用的 shell 编写。
| 模式 | 建议 |
|---|---|
| HTTP 应用 | startCmd 启动服务;readyCmd curl 本地应用端口。 |
| 后台 Worker | readyCmd 检查健康文件、PID、队列连接或 worker 心跳。 |
| 前端预览 | 绑定 0.0.0.0;readyCmd 检查 127.0.0.1:<port>;用户打开 getHost(port)。 |
| 重依赖安装 | 把安装步骤放入构建 RUN,不要放在沙箱启动阶段。 |
常见构建问题
Section titled “常见构建问题”| 现象 | 检查项 |
|---|---|
构建停在 uploaded | 归档未上传、filesHash 变化,或上传完成前启动构建。 |
COPY filesHash is required | 每个使用本地源码的 COPY 步骤都需要 filesHash。 |
沙箱启动但预览返回 502 | startCmd 退出、端口错误,或应用只绑定 localhost。 |
readyCmd 超时 | 沙箱内部目标 localhost 端口没有响应。 |