跳转至

自定义模板

自定义模板用于把业务依赖预置到沙箱启动环境中。相比每次创建沙箱后再安装依赖,模板可以减少准备时间,也能让运行环境更稳定、可复现。

当前建议优先使用自己的 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 重置剩余存活时间。

二、准备环境

安装依赖:

python3 -m venv .venv
source .venv/bin/activate
pip install e2b e2b-code-interpreter python-dotenv

创建 .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 所在可用区不被函数计算支持。

处理方式:

  1. 根据错误信息确认当前 vSwitch 所在可用区。
  2. 在函数计算支持的可用区中选择一个 Zone。
  3. 在同一个 VPC 中新建该 Zone 下的 vSwitch。
  4. 使用这个新的 vSwitch 配置函数计算或相关网络配置。
  5. 重新构建模板并创建沙箱验证。

同一个 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()

运行:

python build_template.py

安装依赖:

npm install e2b @e2b/code-interpreter dotenv
npm install -D tsx typescript @types/node

创建 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();

运行:

npx tsx build_template.ts

验证成功后,脚本会打印 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 创建沙箱:

e2b sandbox create my-code-interpreter-v1

进入沙箱后建议先验证关键依赖:

env | sort | head
python3 --version
which python3

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 builderdirect 构建模式。builder 会使用临时 FC 函数生成适配云沙箱的目标镜像;direct 会直接使用源镜像。

builder 模式还可以配置以下 Header:

Header 取值或格式 说明
X-E2B-Template-Source-Registry-Type acracree 源镜像仓库类型。
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 失败

先确认镜像是否包含代码解释器所需依赖。可以在沙箱中运行:

python3 --version
which python3
env | sort | head -50

如果只是需要判断问题是否出在自己的镜像上,可以用已有 E2B 兼容镜像跑一次对照验证,再回到自己的镜像逐步排查。

5. 模板名称不容易区分

建议在模板名称中包含业务名、基础镜像、关键依赖版本或日期,例如 agent-python313-20260531。生产环境避免覆盖正在使用的模板,先创建新模板并灰度验证。

八、历史兼容方案:layer-build

layer-build 用于把普通镜像转换为 FC E2B 兼容镜像。这个流程需要先生成一个新的适配镜像,再用新镜像构建模板,链路较长。当前推荐优先使用自己的 ACR EE 镜像直接构建模板,新用户通常不需要先走这一步。

只有在以下场景中才建议考虑:

  • 普通镜像无法直接作为模板构建。
  • 无法使用已有 E2B 兼容镜像作为基础镜像。
  • 需要临时兼容旧镜像或旧构建流程。

安装方式:

curl -o- -L https://images.devsapp.cn/e2b/layer-build/latest/install.sh | bash

转换示例:

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 构建模板。