快照(Snapshot)(邀测)

更新时间:
复制 MD 格式

Snapshot 保存运行中沙箱的文件系统与内存状态,可从快照秒级启动同样状态的新沙箱。

功能介绍

Snapshot 功能当前仅支持第二代运行时。

Snapshot 保存运行中沙箱在某一时刻的文件系统与内存状态。创建后的 Snapshot 独立于源沙箱和源模板:删除源沙箱或源模板不会删除 Snapshot;删除 Snapshot 也不会删除源沙箱或源模板。

典型用法:在沙箱中安装依赖、准备工作区后创建一份 Snapshot,之后用这份 Snapshot 秒级启动同样状态的新沙箱,而不必重新构建模板。适用于 Agent 任务断点续跑、环境预热和并行克隆探索等场景。

Snapshot 自创建起默认保留 7 天,到期后自动过期。过期后不再出现在列表中,也不能用于创建沙箱。Snapshot 留存独立于源沙箱生命周期:源沙箱终止或超时回收后,未过期的 Snapshot 仍可使用。

通过 E2B 兼容 SDK 调用,兼容性说明参见E2B 兼容说明。认证与连接参数配置参见使用约束

API 参考

操作

JavaScript / TypeScript

Python

创建

sandbox.createSnapshot({ name? }) / Sandbox.createSnapshot(sandboxId, { name? })

sandbox.create_snapshot(name=...) / Sandbox.create_snapshot(sandbox_id, name=...)

列表

Sandbox.listSnapshots({ sandboxId?, name?, limit?, nextToken? })

Sandbox.list_snapshots(sandbox_id=..., name=..., limit=..., next_token=...)

从 Snapshot 创建沙箱

Sandbox.create(snapshotId | "<TeamName>/<短名>")

Sandbox.create(template=snapshot_id | "<TeamName>/<短名>")

删除

Sandbox.deleteSnapshot(snapshotId | qualifiedName)

Sandbox.delete_snapshot(snapshot_id | qualified_name)

创建 Snapshot 的实例方法与静态方法语义相同。实例方法隐含当前沙箱,无需再传 sandboxId / sandbox_id。列表与删除仅提供静态方法。

返回字段

字段

JavaScript

Python

说明

Snapshot ID

snapshotId

snapshot_id

UUID。创建、删除、从 Snapshot 创建沙箱时优先使用

名称

names

names

有名:["<当前 Team 名>/<短名>:<tag>"];无名:[]

Snapshot 名称与 ID 相互独立。全名仅出现在 names 字段和按名解析中,不替代 Snapshot ID。

使用限制

  • 仅可对运行中的沙箱创建 Snapshot。源沙箱已暂停、正在创建 Snapshot,或当前被其他操作占用时,创建 Snapshot 会失败。

  • 当前仅支持第二代运行时。

  • 有名 Snapshot 要求当前 Team 有名称;Team 无名时只能创建无名 Snapshot。

  • 创建过程中源沙箱 statesnapshotting,此时不可删除该沙箱。完成后可继续使用该沙箱,也可再次创建 Snapshot。

  • 创建可能持续数分钟。SDK 请求超时建议不少于 300 秒(TypeScript:requestTimeoutMs: 300_000;Python:request_timeout=300)。timeoutMs / timeout 控制的是沙箱生命周期,不是 Snapshot 请求超时;默认请求超时通常为 60 秒,不加大时可能在创建完成前失败。

  • 创建 Snapshot 时源模板必须仍存在。创建成功后,即使之后删除源模板,仍可用该 Snapshot 恢复沙箱。

创建 Snapshot

name 可选。省略时创建无名 Snapshot,此后仅可通过 Snapshot ID 访问。

同一 Team 内,同一 (短名, tag) 同时只能存在一份可用 Snapshot,与源模板无关。名称冲突时创建失败,不覆盖已有 Snapshot。不同 tag 可并存。删除后该名称立即释放。

TypeScript

import { Sandbox } from "e2b";

const sandbox = await Sandbox.create("code-interpreter-v1", {
  apiKey: process.env.E2B_API_KEY,
  apiUrl: process.env.E2B_API_URL,
  domain: process.env.E2B_DOMAIN,
  timeoutMs: 300_000,
});

await sandbox.files.write("/app/state.json", '{"step": 1}');

const snapshot = await sandbox.createSnapshot({
  name: "deps-ready",
  requestTimeoutMs: 300_000,
});
// snapshot.snapshotId
// snapshot.names === ["demo-team/deps-ready:default"]

const another = await Sandbox.createSnapshot(sandbox.sandboxId, {
  apiKey: process.env.E2B_API_KEY,
  domain: process.env.E2B_DOMAIN,
  requestTimeoutMs: 300_000,
  name: "deps-ready:v1",
});

Python

import os

from e2b import Sandbox

sandbox = Sandbox.create(
    template="code-interpreter-v1",
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
    timeout=300,
)

sandbox.files.write("/app/state.json", '{"step": 1}')

snapshot = sandbox.create_snapshot(
    name="deps-ready",
    request_timeout=300,
)
# snapshot.snapshot_id
# snapshot.names == ["demo-team/deps-ready:default"]

another = Sandbox.create_snapshot(
    sandbox.sandbox_id,
    name="deps-ready:v1",
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
    request_timeout=300,
)

同一沙箱可创建多份 Snapshot。

名称规则

全名为 <当前 Team 名>/<短名>:<tag>

  • 短名、tag^[_a-zA-Z][-_a-zA-Z0-9]*$,最长 64。必须以字母或下划线开头。

  • Team 名前缀:与 Team 展示名相同,最长 32;允许数字开头,以及空格、点、下划线、连字符(例如默认 Team 的数字名、My Team)。

  • 段内不得包含 /:。Team 名和模板名都不允许 /,因此含且仅含一个 / 的字符串只可能是 Snapshot 全名,不会和模板名冲突。

name

结果

省略 / 空

无名。names = [],仅可通过 Snapshot ID 访问

deps-ready

<当前 Team 名>/deps-ready:default

deps-ready:v1

<当前 Team 名>/deps-ready:v1

demo-team/deps-ready

demo-team/deps-ready:default。前缀必须等于当前 Team 名(大小写不敏感)

demo-team/deps-ready:v1

demo-team/deps-ready:v1

按名创建、恢复或删除时,省略 tag 等价于 default

列出 Snapshot

返回当前 Team 未删除且未过期的 Snapshot,按创建时间倒序。

创建成功后立即调用列表接口时,由于索引延迟,可能暂时看不到刚写入的记录。按 Snapshot ID 或全名恢复沙箱、删除 Snapshot 均不受影响,可直接使用创建接口返回的 snapshotId / names

TypeScript

const paginator = Sandbox.listSnapshots({
  apiKey: process.env.E2B_API_KEY,
  domain: process.env.E2B_DOMAIN,
});
const snapshots = [];
while (paginator.hasNext) {
  snapshots.push(...(await paginator.nextItems()));
}

Sandbox.listSnapshots({
  apiKey: process.env.E2B_API_KEY,
  domain: process.env.E2B_DOMAIN,
  sandboxId: sandbox.sandboxId,
});
Sandbox.listSnapshots({
  apiKey: process.env.E2B_API_KEY,
  domain: process.env.E2B_DOMAIN,
  name: "deps-ready",
});

Python

paginator = Sandbox.list_snapshots(
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
)
snapshots = []
while paginator.has_next:
    snapshots.extend(paginator.next_items())

Sandbox.list_snapshots(
    sandbox_id=sandbox.sandbox_id,
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
)
Sandbox.list_snapshots(
    name="deps-ready",
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
)

参数

说明

sandboxId / sandbox_id

按源沙箱过滤

name

可解析为短名或全名时按段匹配。省略 tag 匹配该名下全部 tag;:v1 或尾部 : 匹配指定 tag。无法解析时对全名做不区分大小写的包含匹配。

limit

每页条数,默认 100,最大 100

nextToken / next_token

分页游标

无名 Snapshot 的 names 为空,name 过滤不会命中。TypeScript 的 listSnapshots / createSnapshot / deleteSnapshot 静态调用请通过环境变量配置 E2B_API_URL,不要传入不受支持的 apiUrl 字段。

从 Snapshot 创建沙箱

Sandbox.create 的模板参数可以是 Snapshot ID,也可以是有名 Snapshot 的全名。完整创建参数说明参见创建沙箱

TypeScript

await Sandbox.create(snapshot.snapshotId, {
  apiKey: process.env.E2B_API_KEY,
  apiUrl: process.env.E2B_API_URL,
  domain: process.env.E2B_DOMAIN,
  timeoutMs: 300_000,
});

await Sandbox.create("demo-team/deps-ready", {
  apiKey: process.env.E2B_API_KEY,
  apiUrl: process.env.E2B_API_URL,
  domain: process.env.E2B_DOMAIN,
  timeoutMs: 300_000,
});

Python

Sandbox.create(
    template=snapshot.snapshot_id,
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
    timeout=300,
)

Sandbox.create(
    template="demo-team/deps-ready",
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
    timeout=300,
)

解析规则:

  1. <Team 名>/<短名><Team 名>/<短名>:<tag>:仅作为 Snapshot 全名。未找到则失败,不会回退为模板。

  2. / 但形态不合法:失败。

  3. 不含 /:值为 UUID 时先按 Snapshot ID 查找,未命中则按模板名创建;非 UUID 的普通模板名直接按模板名创建。

允许覆盖:超时、空闲超时、secureallowInternetAccess、用户 metadata、autoPauseautoResume、网络、自定义沙箱 ID。

不允许覆盖(传入则失败):环境变量、卷 / 文件系统挂载、函数配置、构建 / 镜像、fc. 前缀的系统 metadata。

从 Snapshot 创建的沙箱会占用该 Snapshot。占用期间删除该 Snapshot 会失败。

已过期或已删除的 Snapshot 不能用于创建沙箱。创建 Snapshot 之后删除源模板,仍可用该 Snapshot 恢复。

删除 Snapshot

参数为一个字符串:Snapshot ID,或 names 中的全名。删除成功返回 true,不存在返回 false

参数

行为

Snapshot ID(UUID)

按 ID 删除

全名(demo-team/deps-readydemo-team/deps-ready:default

按全名删除

短名(deps-ready,不含 /

不按 Snapshot 名称删除。先按 ID 查找,未命中则按模板名删除

非法全名(多个 /、空段等)

失败,不会回退为删除模板

TypeScript

await Sandbox.deleteSnapshot(snapshot.snapshotId, {
  apiKey: process.env.E2B_API_KEY,
  domain: process.env.E2B_DOMAIN,
});
await Sandbox.deleteSnapshot(snapshot.names[0], {
  apiKey: process.env.E2B_API_KEY,
  domain: process.env.E2B_DOMAIN,
});

Python

Sandbox.delete_snapshot(
    snapshot.snapshot_id,
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
)
Sandbox.delete_snapshot(
    snapshot.names[0],
    api_key=os.environ["E2B_API_KEY"],
    api_url=os.environ["E2B_API_URL"],
    domain=os.environ["E2B_DOMAIN"],
)
  • Snapshot 仍被已恢复沙箱占用:删除失败。

  • 删除 Snapshot 不删除源模板或源沙箱;删除源沙箱或源模板不删除 Snapshot。

按全名删除时,请使用创建或列表返回的 names[0],或当前 Team 名拼出的全名。不要只传短名。

源沙箱状态

state

说明

snapshotting

正在创建 Snapshot。默认沙箱列表包含此状态。此时不可删除该沙箱

snapshot_failed

创建 Snapshot 失败。默认沙箱列表不含此状态,须按该状态过滤。沙箱可删除

创建失败后,源沙箱仍可使用或删除。

常见问题

条件

结果

源沙箱不存在或不属于当前调用方

创建失败

沙箱运行时不是 MicroVM

创建失败

名称非法,或全名前缀不是当前 Team 名

创建失败

Team 无名却传入 name

创建失败

同名同 tag 已存在

创建失败,不覆盖

源沙箱已暂停、正在创建 Snapshot,或当前被其他操作占用

创建失败

从 Snapshot 创建时覆盖环境变量、挂载或镜像

创建失败

Snapshot 仍被已恢复沙箱占用

删除失败

按全名恢复或删除但 Snapshot 不存在

失败,不回退为模板

创建超时

创建失败,但服务端可能已建成 Snapshot。先增大 requestTimeoutMs / request_timeout。有名 Snapshot:按 name 或全名列表确认后再决定是否重试,避免重复创建。无名 Snapshot:name 过滤无效,应先按源沙箱 sandboxId 列表核对;若已存在目标 Snapshot,直接使用其 ID,不要无条件重试

使用建议

  • 优先保存创建返回的 Snapshot ID;有名 Snapshot 同时保存 names[0],便于按名恢复和删除。

  • 需要在最长 7 天内重复启动同一工作区状态的沙箱时使用 Snapshot;仅需短暂暂停任务时,优先使用暂停与恢复

  • 不用的 Snapshot 及时删除,避免持续产生存储费用。

  • 从 Snapshot 恢复后,仍应在任务结束时调用 sandbox.kill() 释放沙箱资源。