自定义模板¶
自定义模板用于把业务依赖预置到沙箱启动环境中。相比每次创建沙箱后再安装依赖,模板可以减少准备时间,也能让运行环境更稳定、可复现。
当前建议优先使用自己的 ACR EE(ACREE)镜像直接构建模板。这样用户不需要先通过 layer-build 把自己的镜像转换成适配 E2B 的新镜像,再拿转换后的镜像去构建模板,接入链路更短。
如果已有镜像已经注入 envd 等 E2B 运行依赖,并且能被 E2B SDK 直接使用,也可以拿来做快速验证或对照排查。layer-build 的作用就是把普通镜像处理成这种 E2B 兼容镜像;但这条链路需要先生成一个新镜像,再用新镜像构建模板,整体步骤更长,因此不作为首选路径。
一、推荐路径¶
| 场景 | 推荐做法 | 说明 |
|---|---|---|
| 使用自己的基础镜像 | 使用自己的 ACR EE(ACREE)镜像直接构建 | 第一优先级。避免先用 layer-build 生成适配镜像再构建模板的额外步骤。需要提前配置 ACR EE 的 VPC 访问能力,并确保 VPC 中存在函数计算支持可用区下的 vSwitch。 |
快速验证模板构建和 run_code |
使用已有 E2B 兼容镜像 | 这类镜像已经注入 envd 等运行依赖,适合作为 smoke test 和问题对照验证。 |
| 普通镜像无法直接构建 | 再考虑 layer-build |
作为兼容方案保留,不作为首选流程。 |
Note
Template 只定义沙箱启动模板,不提供 timeout 相关参数。沙箱初始存活时间在创建 Sandbox 时通过 timeout 设置;如果不传,当前默认值为 300 秒。沙箱创建后可以通过 set_timeout / setTimeout 重置剩余存活时间。
二、准备环境¶
安装依赖:
创建 .env 文件:
E2B_API_KEY=e2b_xxx
E2B_API_URL=https://api.cn-beijing.e2b.fc.aliyuncs.com
E2B_DOMAIN=cn-beijing.e2b.fc.aliyuncs.com
# 第一优先级:使用自己的 ACR EE 镜像直接构建模板
E2B_TEMPLATE_IMAGE=xl-bj-fc-registry-vpc.cn-beijing.cr.aliyuncs.com/origin/python:3.13-slim
E2B_TEMPLATE_NAME=my-python313-slim
参数说明:
| 参数 | 说明 |
|---|---|
E2B_API_KEY |
云沙箱 API Key。 |
E2B_API_URL |
控制面 API 地址。 |
E2B_DOMAIN |
沙箱连接域名。 |
E2B_TEMPLATE_IMAGE |
用于构建模板的镜像。推荐优先使用自己的 ACR EE 镜像。 |
E2B_TEMPLATE_NAME |
模板名称。建议包含业务名、基础镜像或版本号。 |
三、使用自己的 ACR EE 镜像¶
如果要使用自己的 ACR EE 镜像,例如:
E2B_TEMPLATE_IMAGE=xl-bj-fc-registry-vpc.cn-beijing.cr.aliyuncs.com/origin/python:3.13-slim
E2B_TEMPLATE_NAME=my-python313-slim
可以使用下面的 build_template.py 直接构建模板并创建沙箱验证。
ACR EE 网络要求¶
使用自己的 ACR EE 镜像前,请先确认以下条件:
- ACR EE 实例至少配置了一个专有网络。
- 该专有网络下至少有一个 vSwitch 位于函数计算支持的可用区。
- ACR EE 镜像仓库、VPC、vSwitch 与云沙箱所在地域匹配,例如本文默认使用北京地域。
- 如果镜像需要私网拉取,请确保 ACR EE 访问控制和 VPC 配置已经允许对应网络访问。
函数计算支持的可用区会随地域和产品能力调整,最新列表请参考函数计算支持的可用区。
vSwitch is in unsupported zone¶
如果构建或运行过程中遇到 vSwitch is in unsupported zone,说明当前选择的 vSwitch 所在可用区不被函数计算支持。
处理方式:
- 根据错误信息确认当前 vSwitch 所在可用区。
- 在函数计算支持的可用区中选择一个 Zone。
- 在同一个 VPC 中新建该 Zone 下的 vSwitch。
- 使用这个新的 vSwitch 配置函数计算或相关网络配置。
- 重新构建模板并创建沙箱验证。
同一个 VPC 内不同可用区的交换机默认内网互通。因此,即使业务资源在其他可用区,也可以在同一个 VPC 中新增一个函数计算支持可用区下的 vSwitch,用于完成函数计算侧网络接入。
构建并验证¶
创建 build_template.py:
import os
import sys
import time
from dotenv import load_dotenv
from e2b import Template, default_build_logger
from e2b_code_interpreter import Sandbox
RUN_CODE = "print('hello')"
def require_env(name: str) -> str:
value = os.environ.get(name, "").strip()
if not value:
print(f"ERROR: 缺少环境变量 {name}")
sys.exit(1)
return value
def optional_env(name: str) -> str | None:
value = os.environ.get(name, "").strip()
return value or None
def main() -> None:
load_dotenv()
image = require_env("E2B_TEMPLATE_IMAGE")
name = optional_env("E2B_TEMPLATE_NAME") or f"template-build-{int(time.time())}"
conn_opts = {
"api_key": require_env("E2B_API_KEY"),
"api_url": require_env("E2B_API_URL"),
"domain": require_env("E2B_DOMAIN"),
}
print(f"from_image: {image}")
print(f"template_name: {name}")
build = Template.build(
Template().from_image(image),
name=name,
cpu_count=2,
memory_mb=2048,
skip_cache=False,
on_build_logs=default_build_logger(),
**conn_opts,
)
sandbox = Sandbox.create(
template=build.template_id,
timeout=900,
**conn_opts,
)
try:
print(f"template_id: {build.template_id}")
print(f"build_id: {build.build_id}")
print(f"sandbox_id: {sandbox.sandbox_id}")
execution = sandbox.run_code(RUN_CODE, timeout=60, request_timeout=120)
stdout = "".join(execution.logs.stdout or [])
stderr = "".join(execution.logs.stderr or [])
print(f"run_code: {RUN_CODE}")
print(f"stdout: {stdout.strip()}")
print(f"stderr: {stderr.strip()}")
print(f"error: {execution.error}")
if execution.error is not None:
raise RuntimeError(f"run_code 执行失败: {execution.error}")
if stdout.strip() != "hello":
raise RuntimeError(f"run_code stdout 不符合预期: {stdout!r}")
finally:
sandbox.kill()
print("sandbox 已销毁")
if __name__ == "__main__":
main()
运行:
安装依赖:
创建 build_template.ts:
import 'dotenv/config';
import { Sandbox, Template } from 'e2b';
const E2B_API_KEY = process.env.E2B_API_KEY!;
const image = process.env.E2B_TEMPLATE_IMAGE!;
const templateName = process.env.E2B_TEMPLATE_NAME
?? `template-build-${Math.floor(Date.now() / 1000)}`;
async function main() {
console.log(`from_image: ${image}`);
console.log(`template_name: ${templateName}`);
const registryTemplate = Template().fromImage(image);
const buildInfo = await Template.build(registryTemplate, templateName, {
apiKey: E2B_API_KEY,
cpuCount: 2,
memoryMB: 2048,
});
console.log(`template built: ${buildInfo.name}`);
const sbx = await Sandbox.create({
template: buildInfo.name,
apiKey: E2B_API_KEY,
timeoutMs: 900_000,
});
try {
console.log(`sandbox_id: ${sbx.sandboxId}`);
const result = await sbx.commands.run("python3 -c \"print('hello')\"");
console.log(`stdout: ${result.stdout.trim()}`);
if (result.stdout.trim() !== 'hello') {
throw new Error(`unexpected output: ${result.stdout}`);
}
} finally {
await sbx.kill();
console.log('sandbox destroyed');
}
}
main();
运行:
验证成功后,脚本会打印 template_id(或 template name)、sandbox_id,并输出 hello。
四、使用 E2B 兼容镜像做对照验证¶
E2B 兼容镜像指已经注入 envd 等运行依赖、能被 E2B SDK 直接使用的镜像。它可能来自已有构建流程,也可能是普通镜像经过 layer-build 处理后的产物。
如果只是想快速确认模板构建和 run_code 链路是否正常,可以使用已有 E2B 兼容镜像做对照验证:
E2B_TEMPLATE_IMAGE=fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/code-interpreter-v1:v0.0.18
E2B_TEMPLATE_NAME=my-code-interpreter-v1
然后复用上一节的 build_template.py 进行构建和验证。
五、查看模板并创建沙箱¶
如果已经安装 E2B CLI,可以通过模板列表确认构建状态:
export E2B_API_KEY=e2b_xxx
export E2B_ACCESS_TOKEN=$E2B_API_KEY
export E2B_API_URL=https://api.cn-beijing.e2b.fc.aliyuncs.com
export E2B_DOMAIN=cn-beijing.e2b.fc.aliyuncs.com
e2b template list
当模板状态为 ready 后,可以使用模板名称或 template_id 创建沙箱:
进入沙箱后建议先验证关键依赖:
六、高级配置:通过 Header 调整模板构建¶
sandbox-gateway 支持通过 Template.build(..., headers={...}) 传入 X-E2B-Template-* 扩展 Header。只有需要显式指定构建模式、目标镜像、私有仓库凭证或 ACR EE 网络时,才需要配置这些 Header。
其中 builder 用于把普通业务镜像处理成可用于云沙箱模板的镜像。构建时,平台会临时启动一个 FC 函数,由这个 builder 函数拉取源镜像、加入云沙箱运行所需的依赖,并推送为目标镜像;模板最终使用这个目标镜像创建沙箱运行环境。
示例:
headers = {
"X-E2B-Template-Build-Mode": "builder",
"X-E2B-Template-Source-Registry-Type": "acree",
"X-E2B-Template-Dest-Image-Ref": "example-registry.cn-beijing.cr.aliyuncs.com/example/app:e2b",
"X-E2B-Template-Source-Username": "source-user",
"X-E2B-Template-Source-Password": "source-password",
"X-E2B-Template-Dest-Username": "dest-user",
"X-E2B-Template-Dest-Password": "dest-password",
"X-E2B-Template-Source-ACREE-Instance-ID": "cri-example",
"X-E2B-Template-Source-VPC-ID": "vpc-example",
"X-E2B-Template-Source-VSwitch-IDs": "vsw-example-a,vsw-example-b",
"X-E2B-Template-Source-Security-Group-ID": "sg-example",
}
build = Template.build(
Template().from_image(image),
name=name,
cpu_count=2,
memory_mb=2048,
skip_cache=False,
on_build_logs=default_build_logger(),
headers=headers,
**conn_opts,
)
支持的 Header:
| Header | 取值或格式 | 说明 |
|---|---|---|
X-E2B-Template-Build-Mode |
builder、direct |
构建模式。builder 会使用临时 FC 函数生成适配云沙箱的目标镜像;direct 会直接使用源镜像。 |
builder 模式还可以配置以下 Header:
| Header | 取值或格式 | 说明 |
|---|---|---|
X-E2B-Template-Source-Registry-Type |
acr、acree |
源镜像仓库类型。 |
X-E2B-Template-Dest-Image-Ref |
完整镜像地址 | 目标镜像地址。 |
X-E2B-Template-Source-Username |
字符串 | 源镜像拉取用户名。 |
X-E2B-Template-Source-Password |
字符串 | 源镜像拉取密码或 token。 |
X-E2B-Template-Dest-Username |
字符串 | 目标镜像推送用户名。 |
X-E2B-Template-Dest-Password |
字符串 | 目标镜像推送密码或 token。 |
X-E2B-Template-Source-ACREE-Instance-ID |
ACR EE 实例 ID | 源 ACR EE 实例 ID。 |
X-E2B-Template-Source-VPC-ID |
VPC ID | 访问源镜像仓库使用的 VPC。 |
X-E2B-Template-Source-VSwitch-IDs |
vSwitch ID 列表,逗号分隔 | 访问源镜像仓库使用的交换机。 |
X-E2B-Template-Source-Security-Group-ID |
安全组 ID | 访问源镜像仓库使用的安全组。 |
构建模式说明:
builder:使用临时 FC 函数处理源镜像,加入云沙箱运行依赖,并生成适配云沙箱的目标镜像,适合普通业务镜像。direct:不执行镜像转换,直接把源镜像作为custom-container模板函数镜像。源镜像需要已经具备 E2B 运行依赖。
注意事项:
- 密码、token 等敏感信息建议只从
.env或环境变量读取,不要写入代码仓库,也不要打印到日志。 - VPC、vSwitch、安全组 Header 只用于 builder 访问源镜像仓库,不影响最终模板和沙箱的网络配置。
七、排障建议¶
1. 模板构建慢¶
优先检查自己的 ACR EE 镜像体积、网络链路、镜像层缓存和 ACR EE 私网访问配置。基础镜像越大,首次构建通常越慢。
如果只是排查模板构建链路是否正常,可以临时使用已有 E2B 兼容镜像做对照验证。这类镜像已经注入 envd 等运行依赖,通常更容易排除镜像适配问题。
2. ACR EE 镜像拉取失败¶
检查镜像地址、地域、命名空间、仓库权限、VPC 绑定和访问控制配置。使用私有 ACR EE 镜像时,网络配置错误比 SDK 参数错误更常见。
3. vSwitch 所在可用区不支持¶
参考 “vSwitch is in unsupported zone” 小节,在同一个 VPC 中创建函数计算支持可用区下的 vSwitch,然后使用该 vSwitch 重新配置网络。
4. 沙箱创建成功但 run_code 失败¶
先确认镜像是否包含代码解释器所需依赖。可以在沙箱中运行:
如果只是需要判断问题是否出在自己的镜像上,可以用已有 E2B 兼容镜像跑一次对照验证,再回到自己的镜像逐步排查。
5. 模板名称不容易区分¶
建议在模板名称中包含业务名、基础镜像、关键依赖版本或日期,例如 agent-python313-20260531。生产环境避免覆盖正在使用的模板,先创建新模板并灰度验证。
八、历史兼容方案:layer-build¶
layer-build 用于把普通镜像转换为 FC E2B 兼容镜像。这个流程需要先生成一个新的适配镜像,再用新镜像构建模板,链路较长。当前推荐优先使用自己的 ACR EE 镜像直接构建模板,新用户通常不需要先走这一步。
只有在以下场景中才建议考虑:
- 普通镜像无法直接作为模板构建。
- 无法使用已有 E2B 兼容镜像作为基础镜像。
- 需要临时兼容旧镜像或旧构建流程。
安装方式:
转换示例:
layer-build \
--source registry.cn-beijing.aliyuncs.com/example/app:latest \
--target registry.cn-beijing.aliyuncs.com/example/app:latest-envd \
--source_username "u1" \
--source_password "p1" \
--target_username "u1" \
--target_password "p1"
转换完成后,把 E2B_TEMPLATE_IMAGE 设置为 *-envd 目标镜像,再使用本文前面的 build_template.py 构建模板。