All Products
Search
Document Center

Agent Sandbox:Build and manage custom templates with code

Last Updated:Oct 12, 2026

Use the Agent Sandbox OpenAPI SDK to build, query, update, and delete custom templates in code. Choose the image source and build method for each template generation, and configure the network access of the sandbox after a virtual private cloud (VPC) is connected.

A custom template defines the image and configurations that a sandbox requires. This topic describes the image sources and build methods of second-generation and first-generation templates, and then describes the network configuration after a VPC is connected. The examples use Python to call the Agent Sandbox OpenAPI SDK. The TypeScript, Go, and Java SDKs provide the same capabilities.

The supported image sources and configuration items vary by generation. Before writing code, check the template generation.

Item

Second-generation template

First-generation template

Image source

Official public images and Container Registry Enterprise Edition (ACR EE) images

Official public images, ACR EE images, and Open Container Initiative (OCI)-compliant image registries

Build method and startup configuration

Supports a start command (start_command) and a ready command (ready_command)

Uses build_config to control build actions (copy and envd_inject), which are derived from the image source by default. Does not support start_command or ready_command

Disk size measurement

disk_size includes the size of the image itself. The writable space = disk size - image size

disk_size is the writable space and excludes the size of the image itself

Log configuration

All examples include log_config

All examples include log_config

For the complete capability differences between the two runtime generations, see Differences between first-generation and second-generation sandbox runtimes.

Before you begin

This section describes the preparations that the following examples have in common. Each later section provides a complete build example based on these preparations. The examples that create and access sandboxes also use the E2B SDK. Install the E2B SDK and configure its credential environment variables in advance.

Important

The preparations and examples in this topic create billable resources: a Container Registry Enterprise Edition (ACR EE) instance, a Simple Log Service (SLS) project and Logstore, and, for Scenario 3, an Internet NAT gateway and an elastic IP address (EIP). Each template build and each sandbox run also consume compute resources.

These resources keep incurring charges until you release them. Deleting a template does not release the ACR EE instance, the SLS resources, the Internet NAT gateway, or the EIP. Release the resources that you no longer need in the console of each service, and see the billing documentation of Agent Sandbox and of each referenced service for billing details.

  1. Activate Function Compute and Agent Sandbox, create a Team in the Agent Sandbox console, and obtain the Team ID.

  2. Prepare an Alibaba Cloud account or a Resource Access Management (RAM) user, and grant the template API permissions to the calling identity. Example of a minimum permission policy:

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sandbox:CreateTemplate",
            "sandbox:GetTemplate",
            "sandbox:ListTemplates",
            "sandbox:UpdateTemplate",
            "sandbox:DeleteTemplate"
          ],
          "Resource": "*"
        }
      ]
    }

    Template resources support fine-grained authorization by Team. The resource format is acs:sandbox:<region>:<account-id>:teams/<team-id>/templates/*.

  3. Check the region of the template. This example uses cn-hangzhou. Replace it with the destination region.

  4. Prepare the image address. For a private image, prepare the corresponding credentials and image pull network. See the image source section of each generation.

  5. Prepare log resources: Create a Simple Log Service (SLS) project and Logstore in the same region as Agent Sandbox so that log_config can deliver build and runtime logs.

Install the SDK. This example uses Python:

python3 -m venv .venv
source .venv/bin/activate
pip install "alibabacloud_sandbox20260820>=1.1.0"

Configure the credential environment variables:

export ALIBABA_CLOUD_ACCESS_KEY_ID="<your-access-key-id>"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="<your-access-key-secret>"
# If you use a Security Token Service (STS) token, also configure:
# export ALIBABA_CLOUD_SECURITY_TOKEN="<your-security-token>"

Common initialization code. All later examples are based on this code:

import os
import time

from alibabacloud_sandbox20260820 import models
from alibabacloud_sandbox20260820.client import Client as SandboxClient
from alibabacloud_tea_openapi import models as open_api_models

REGION = "cn-hangzhou"
TEAM_ID = "<your-team-id>"

config = open_api_models.Config(
    access_key_id=os.environ["ALIBABA_CLOUD_ACCESS_KEY_ID"],
    access_key_secret=os.environ["ALIBABA_CLOUD_ACCESS_KEY_SECRET"],
    region_id=REGION,
    endpoint=f"sandbox.{REGION}.aliyuncs.com",
)
pop_client = SandboxClient(config)


def wait_ready(template_id, timeout=900):
    """Poll the template build status until a final state is reached, and return status.state."""
    deadline = time.time() + timeout
    while time.time() < deadline:
        resp = pop_client.get_template(
            template_id, models.GetTemplateRequest(team_id=TEAM_ID))
        state = resp.body.status.state
        if state in ("ready", "error"):
            if state == "error":
                print(f"Build failed: {resp.body.status.reason.message}")
            return state
        time.sleep(10)
    return "timeout"

Image requirements

A custom image must meet the requirements listed in the following table, which are graded as mandatory, conditional, or recommended. Second-generation templates have stricter requirements on the Linux distribution.

Level

Requirement

Impact if not met

Mandatory

The architecture is linux/amd64. The manifest list of a multi-architecture image must contain the linux/amd64 variant

The template fails to build

Mandatory

Image acceleration is not enabled for the ACR image

The template fails to build

Mandatory

/etc/passwd and /etc/group are regular files and are writable

The sandbox cannot initialize the default user, and fails to start

Conditional

Bash is located at the fixed path /bin/bash in the image, rather than being discoverable only through PATH

commands.run and pseudo-terminal (PTY) calls fail

Conditional

PATH contains python3 or python

Python run_code is unavailable

Conditional

PATH contains node

JavaScript run_code is unavailable

Conditional

Provide git, openssh-client, CA certificates, and compiler toolchains as needed

The corresponding Git, SSH, HTTPS, and install-from-source operations are unavailable

Recommended

The system PATH contains at least /usr/local/bin, /usr/bin, and /bin

Common commands may be unavailable in the logon shell

When you push an image to your own image repository, do not push images with different content to the same tag. Each different image must use a new and unique tag, such as a version number, date, or commit ID, and the template must always reference that specific tag.

Second-generation templates

Second-generation templates use lightweight virtual machine (MicroVM) isolation and support snapshots. The start command and the runtime environment executed during the build are fixed in the template snapshot. When you create a sandbox from the template, the runtime state is restored directly, which makes creation significantly faster than that of a first-generation template. The image of a second-generation template must be based on Ubuntu or Debian, and must retain system components such as systemd, openssh-server, and sudo.

Always specify disk_size explicitly (this example uses 15360 MB) to avoid specification validation differences caused by platform default values that change between versions.

Select an image source

Official public image

Official public images are provided in all supported regions. The address of an image for a second-generation template is in the fc-e2b-registry.<region>.cr.aliyuncs.com/runtime-v2/<image-name>:<tag> format. You do not need to prepare an image repository, credentials, or network configurations. The region in the image address must be the same as the region of the template.

Example of a minimal build:

resp = pop_client.create_template(
    models.CreateTemplateRequest(
        body=models.CreateTemplateInput(
            name=f"template-gen2-demo-{int(time.time())}",
            team_id=TEAM_ID,
            runtime_config=models.CreateTemplateRuntimeConfig(
                cpu=2,
                memory_size=2048,
                disk_size=15360,
                # Deliver build and runtime logs to SLS in the same region.
                log_config=models.CreateTemplateLogConfig(
                    project="<sls-project>",
                    logstore="<sls-logstore>",
                ),
                sandbox_config=models.CreateTemplateSandboxConfig(
                    image=f"fc-e2b-registry.{REGION}.cr.aliyuncs.com/runtime-v2/base:v0.0.53",
                    generation=2,  # Required. 2 specifies a second-generation template.
                ),
            ),
        )
    )
)
template_id = resp.body.template_id
state = wait_ready(template_id)
assert state == "ready"

ACR EE image

Use your own image stored in an ACR EE instance.

Preparations:

  1. Create an ACR EE instance in the same Alibaba Cloud account and region as Agent Sandbox. The Economy Edition is not supported.

  2. Add a VPC to the ACR EE instance so that Agent Sandbox can pull images over the VPC.

  3. Create a namespace and an image repository, push the image, and use the VPC domain name of the instance in the image address (-vpc suffix). Example: <instance>-registry-vpc.cn-hangzhou.cr.aliyuncs.com/<namespace>/<image>:<tag>.

Network constraints:

  • At least one VPC association is added to the access control list of the ACR EE instance and is in the Active state. Agent Sandbox pulls images over the access IP assigned in the associated VPC. A newly created association is in the Activating state for a period of time, and an expired association causes the pull to fail. Check the association status and access IP on the Access Control page of the instance.

  • The VPC of the image pull network must be a VPC associated with the ACR EE instance, and at least one vSwitch in the VPC must be located in a zone supported by Function Compute.

  • The ACR EE image repository, VPC, vSwitch, and Agent Sandbox must be located in the same region.

  • The CIDR block of the VPC must use a private address range specified in RFC 1918, which is 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16. A CIDR block that is allocated for use on the Internet cannot be used as a private CIDR block.

  • At least one custom security group must be configured for the VPC, and its outbound rules must allow TCP port 443. By default, the outbound direction of a basic security group allows all access, and no outbound rule is required. By default, the outbound direction of an advanced security group denies all access, so an outbound rule that allows TCP port 443 must be added.

  • Make sure that the ACR EE instance has an inbound elastic network interface (ENI) in the VPC. If the ENI is deleted, re-associate the VPC to recreate the ENI.

The zones supported by Function Compute change based on regions and features. For the latest list, see Configure network.

Pull method: If only image is specified, the platform derives the ACR EE instance and the repository type from the image address. The platform then pulls the image by using the temporary authorization of the instance and derives the pull network from the VPC associated with the instance. To specify the instance, credentials, or pull network explicitly, also pass acr_instance_id, registry_config.auth_config, and registry_config.network_config. If the pull fails because the vSwitch derived from the instance is located in an unsupported zone, use network_config to explicitly specify the three VPC parameters (vpc_id, v_switch_id, and security_group_id).

resp = pop_client.create_template(
    models.CreateTemplateRequest(
        body=models.CreateTemplateInput(
            name=f"template-gen2-acree-{int(time.time())}",
            team_id=TEAM_ID,
            runtime_config=models.CreateTemplateRuntimeConfig(
                cpu=2,
                memory_size=2048,
                disk_size=15360,
                log_config=models.CreateTemplateLogConfig(
                    project="<sls-project>",
                    logstore="<sls-logstore>",
                ),
                sandbox_config=models.CreateTemplateSandboxConfig(
                    image="<instance>-registry-vpc.cn-hangzhou.cr.aliyuncs.com/<namespace>/<image>:<tag>",
                    generation=2,
                    acr_instance_id="cri-xxxxxx",
                    registry_config=models.CreateTemplateRegistryConfig(
                        auth_config=models.CreateTemplateRegistryAuthConfig(
                            user_name="<username>",
                            password="<password>",
                        ),
                        network_config=models.CreateTemplateRegistryNetworkConfig(
                            vpc_id="<vpc-id>",
                            v_switch_id="<vsw-id>",
                            security_group_id="<sg-id>",
                        ),
                    ),
                ),
            ),
        )
    )
)

Configure the start command and ready command

The following example shows how the two commands work together for a pre-deployed HTTP service. During the build, the platform runs start_command as a background process to start the service. The platform then repeatedly runs ready_command until the command returns exit code 0, which means that the service is ready. Then, the platform creates a template snapshot for the sandbox that is still running. When you create a sandbox from this template, the service is already running and can be accessed immediately. The start command is not run again.

  • Execution time: Both commands are executed only during the template build, and the results are fixed in the snapshot. They are not replayed when a sandbox is created.

  • Format: Both commands are shell commands in string format, and both parameters are optional. If start_command is not specified, no extra start command is executed.

  • Failure handling: If start_command exits prematurely, ready_command keeps failing, or the wait time exceeds 5 minutes, the template build fails. If ready_command is incorrectly specified, the typical symptom is a build timeout instead of a parameter error.

  • Troubleshoot by using logs: Command output and failure causes are delivered to SLS by using log_config. View the logs in the corresponding Logstore.

resp = pop_client.create_template(
    models.CreateTemplateRequest(
        body=models.CreateTemplateInput(
            name=f"template-gen2-service-{int(time.time())}",
            team_id=TEAM_ID,
            runtime_config=models.CreateTemplateRuntimeConfig(
                cpu=2,
                memory_size=2048,
                disk_size=15360,
                log_config=models.CreateTemplateLogConfig(
                    project="<sls-project>",
                    logstore="<sls-logstore>",
                ),
                sandbox_config=models.CreateTemplateSandboxConfig(
                    image=f"fc-e2b-registry.{REGION}.cr.aliyuncs.com/runtime-v2/base:v0.0.53",
                    generation=2,
                    # Run as a background process during the build.
                    start_command="python3 -m http.server 8000",
                    # Run repeatedly. An exit code of 0 once means the service is ready.
                    ready_command="curl -sf http://localhost:8000/ > /dev/null",
                ),
            ),
        )
    )
)
template_id = resp.body.template_id
state = wait_ready(template_id)
assert state == "ready"

After the template is built and becomes ready, use the E2B SDK to create a sandbox and access the service:

from e2b import Sandbox

sandbox = Sandbox.create(
    template=template_id,
    timeout=600,
    # The SDK automatically reads the E2B_API_KEY, E2B_API_URL, and E2B_DOMAIN environment variables.
    api_url=f"https://api.{REGION}.e2b.fc.aliyuncs.com",
    domain=f"{REGION}.e2b.fc.aliyuncs.com",
)
try:
    host = sandbox.get_host(8000)
    print(f"https://{host}")
finally:
    sandbox.kill()

First-generation templates

Select an image source

  • Official public image: The address of an image for a first-generation template is in the fc-e2b-registry.<region>.cr.aliyuncs.com/runtime/<image-name>:<tag> format (the runtime-v2 prefix of a second-generation template is different). No credentials or network configurations are required. The platform uses the image directly and does not run the build injection.

  • ACR EE image: The instance preparations, network constraints, and pull method are the same as those of the second-generation ACR EE image. Use the -vpc domain name in the image address. For an image in the same account, no credentials are required, and the platform pulls the image by using the temporary authorization of the instance.

  • OCI-compliant image registry: any standard OCI registry reachable over the Internet or private in a VPC. Provide the registry credentials in registry_config.auth_config (user_name and password, which must have both the pull and push permissions). For a private registry in a VPC, also use registry_config.network_config to provide the three VPC parameters of the pull network (vpc_id, v_switch_id, and security_group_id).

Select a build method

When you build an unofficial image, a first-generation template uses build_config to control two build actions: copy (pushes the build output as the destination image) and envd_inject (injects the sandbox runtime dependencies).

Item

Build with injection (copy and envd_inject enabled)

Use the source image directly (both disabled)

Build process

The platform pulls the source image, injects the sandbox runtime dependencies, and pushes the result as the destination image

The platform uses the source image directly, without injection or modification

Input requirements

The source image does not need to be modified. The destination repository credentials have the push permission

The image already contains the sandbox runtime dependencies

Scenarios

Common custom images (default method)

Official public images, images that already integrate the runtime dependencies, or read-only image repositories

If build_config is not specified, the build method is derived from the source image. An official public image is used directly without a build. Other images are built with injection. Note that copy and envd_inject must be enabled or disabled together. If only one of them is enabled, 400 is returned.

Use the source image directly

The platform automatically uses an official public image directly as the source image, and no extra configuration is required. This applies to a custom image only if the image already contains the sandbox runtime dependencies.

resp = pop_client.create_template(
    models.CreateTemplateRequest(
        body=models.CreateTemplateInput(
            name=f"template-gen1-direct-{int(time.time())}",
            team_id=TEAM_ID,
            runtime_config=models.CreateTemplateRuntimeConfig(
                cpu=2,
                memory_size=2048,
                log_config=models.CreateTemplateLogConfig(
                    project="<sls-project>",
                    logstore="<sls-logstore>",
                ),
                sandbox_config=models.CreateTemplateSandboxConfig(
                    image=f"fc-e2b-registry.{REGION}.cr.aliyuncs.com/runtime/code-interpreter-v1:v0.0.53",
                    generation=1,
                ),
            ),
        )
    )
)

The differences between image sources are described in the previous section. This section focuses on how to select a build method, and does not repeat the same configurations.

Build with injection (default)

If build_config is not specified, the build uses injection. Two common scenarios apply, depending on the repository that stores the image:

Scenario 1: Private ACR EE image over a VPC

resp = pop_client.create_template(
    models.CreateTemplateRequest(
        body=models.CreateTemplateInput(
            name=f"template-gen1-builder-{int(time.time())}",
            team_id=TEAM_ID,
            runtime_config=models.CreateTemplateRuntimeConfig(
                cpu=2,
                memory_size=2048,
                log_config=models.CreateTemplateLogConfig(
                    project="<sls-project>",
                    logstore="<sls-logstore>",
                ),
                sandbox_config=models.CreateTemplateSandboxConfig(
                    image="<instance>-registry-vpc.cn-hangzhou.cr.aliyuncs.com/<namespace>/<image>:<tag>",
                    generation=1,  # Required. 1 specifies a first-generation template.
                ),
            ),
        )
    )
)
template_id = resp.body.template_id
state = wait_ready(template_id)
assert state == "ready"

Scenario 2: Private OCI registry in a VPC

This applies to a self-managed private registry whose domain name is reachable only within a VPC, such as a Harbor instance deployed on an Elastic Compute Service (ECS) instance in a VPC. Constraints:

  • The registry must provide services over HTTPS and listen on port 443. Custom ports and HTTP are not supported.

  • Specify registry_config.network_config (the three VPC parameters vpc_id, v_switch_id, and security_group_id, which must be provided together).

  • A registry that uses a self-signed certificate must also skip certificate verification in cert_config (insecure=True). Otherwise, the build fails with an x509 certificate error when the platform pulls the source image.

  • Pass credentials by using auth_config as usual. The credentials must have both the pull and push permissions.

resp = pop_client.create_template(
    models.CreateTemplateRequest(
        body=models.CreateTemplateInput(
            name=f"template-gen1-oci-{int(time.time())}",
            team_id=TEAM_ID,
            runtime_config=models.CreateTemplateRuntimeConfig(
                cpu=2,
                memory_size=2048,
                log_config=models.CreateTemplateLogConfig(
                    project="<sls-project>",
                    logstore="<sls-logstore>",
                ),
                sandbox_config=models.CreateTemplateSandboxConfig(
                    image="registry.internal.example.com/<namespace>/<image>:<tag>",
                    generation=1,
                    registry_config=models.CreateTemplateRegistryConfig(
                        auth_config=models.CreateTemplateRegistryAuthConfig(
                            user_name="<username>",
                            password="<password>",
                        ),
                        network_config=models.CreateTemplateRegistryNetworkConfig(
                            vpc_id="<vpc-id>",
                            v_switch_id="<vsw-id>",
                            security_group_id="<sg-id>",
                        ),
                        cert_config=models.CreateTemplateRegistryCertConfig(
                            insecure=True,  # Specify this for a self-signed certificate
                        ),
                    ),
                ),
            ),
        )
    )
)
template_id = resp.body.template_id
state = wait_ready(template_id)
assert state == "ready"

Manage templates

Query template information and build status

Use ListTemplates to query the templates of a Team by page, and use GetTemplate to query the configuration and build status of a single template. The status.state parameter has the following valid values: pending (waiting for the build), building (build in progress), updating (rebuilding after a configuration update), ready (ready to create sandboxes), and error (the build failed). The status.reason.message parameter provides the cause of a failure. Poll at an interval of 5 to 10 seconds.

Complete example that lists all templates by paging:

import os

from alibabacloud_sandbox20260820 import models
from alibabacloud_sandbox20260820.client import Client as SandboxClient
from alibabacloud_tea_openapi import models as open_api_models

REGION = "cn-hangzhou"
TEAM_ID = "<your-team-id>"

config = open_api_models.Config(
    access_key_id=os.environ["ALIBABA_CLOUD_ACCESS_KEY_ID"],
    access_key_secret=os.environ["ALIBABA_CLOUD_ACCESS_KEY_SECRET"],
    region_id=REGION,
    endpoint=f"sandbox.{REGION}.aliyuncs.com",
)
pop_client = SandboxClient(config)

next_token = None
while True:
    request = models.ListTemplatesRequest(team_id=TEAM_ID)
    if next_token:
        request.next_token = next_token
    response = pop_client.list_templates(request)
    for template in response.body.templates:
        print(template.template_id, template.name, template.status.state)
    next_token = response.body.next_token
    if not next_token:
        break

Create a sandbox from a built template

After the template enters the ready state, use the E2B SDK to create a sandbox and check the result:

from e2b import Sandbox

sandbox = Sandbox.create(
    template=template_id,
    timeout=600,
    api_url=f"https://api.{REGION}.e2b.fc.aliyuncs.com",
    domain=f"{REGION}.e2b.fc.aliyuncs.com",
)
try:
    result = sandbox.commands.run("printf hello")
    print(result.stdout)
finally:
    sandbox.kill()

Modify configurations and rebuild

Use UpdateTemplate to modify configuration items in place, such as the image, specification, and network configurations. After you submit the request, the platform automatically rebuilds the template, and the template returns to the updating state and restores the ready state after the build is complete:

pop_client.update_template(
    template_id,
    models.UpdateTemplateRequest(
        team_id=TEAM_ID,
        body=models.PublicUpdateTemplateInput(
            runtime_config=models.PublicUpdateTemplateRuntimeConfig(
                cpu=4,
                memory_size=4096,
            ),
        ),
    ),
)
state = wait_ready(template_id)
assert state == "ready"
  • Pass only the configuration items that you want to modify. The items that you do not pass keep their original values.

Delete a template that is no longer used

Warning

Deleting a template cannot be undone. After the deletion, the template and its snapshot no longer exist, and the template cannot be used to create sandboxes. To use the template again, you must build it again.

Before you delete a template, make sure that your workloads no longer use it to create sandboxes. After a template is deleted, its name is released immediately, and you can create a new template with the same name.

pop_client.delete_template(
    template_id, models.DeleteTemplateRequest(team_id=TEAM_ID))
  • A template can be deleted in any state, including the building state. The deletion terminates the build in progress.

Network configuration (advanced)

This section uses a second-generation template as an example to describe how a sandbox accesses resources after vpc_config is configured, and focuses on how vpc_config works with internet_access. If no VPC is configured, the sandbox can access the Internet over the platform egress by default, and the egress IP address is not fixed.

Select a scenario

Scenario

vpc_config

internet_access

Internet egress requirements of the VPC

Internet access result

Access the VPC, and access the Internet over the platform egress

Configured

Enabled (default)

No fixed Internet egress is required

The Internet is accessible, and the egress IP address is not fixed

Access the VPC, but not the Internet

Configured

Disabled

The VPC provides no Internet egress

The Internet is inaccessible

Access the VPC, and access the Internet over a fixed IP address

Configured

Disabled

The VPC provides an Internet NAT gateway, an elastic IP address (EIP), and the corresponding routes and SNAT rules

The Internet is accessible over the specified fixed egress IP address

Note that the CIDR block of the VPC must use a private address range specified in RFC 1918 (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16). The vSwitch must be located in a zone supported by Function Compute.

Scenario 1: Access the VPC and the Internet over a non-fixed egress IP address

Configure vpc_config, and keep internet_access enabled, which is the default:

runtime_config=models.CreateTemplateRuntimeConfig(
    cpu=2,
    memory_size=2048,
    disk_size=15360,
    internet_access=True,
    vpc_config=models.CreateTemplateVPCConfig(
        vpc_id="<vpc-id>",
        v_switch_ids=["<vsw-id>"],
        security_group_id="<sg-id>",
    ),
    log_config=models.CreateTemplateLogConfig(
        project="<sls-project>",
        logstore="<sls-logstore>",
    ),
    sandbox_config=models.CreateTemplateSandboxConfig(
        image=f"fc-e2b-registry.{REGION}.cr.aliyuncs.com/runtime-v2/base:v0.0.53",
        generation=2,
    ),
)

Verification: After the sandbox is created, access a resource in the VPC, such as an internal domain name or private IP address, and an Internet address, such as curl https://www.aliyun.com. Both are accessible. Scenario 1 (vpc_config configured and internet_access left enabled) does not provide a fixed Internet egress IP address.

Scenario 2: Access only the VPC but not the Internet

Configure vpc_config, and disable internet_access. Also make sure that the VPC itself provides no Internet egress:

runtime_config=models.CreateTemplateRuntimeConfig(
    cpu=2,
    memory_size=2048,
    disk_size=15360,
    internet_access=False,
    vpc_config=models.CreateTemplateVPCConfig(
        vpc_id="<vpc-id>",
        v_switch_ids=["<vsw-id>"],
        security_group_id="<sg-id>",
    ),
    log_config=models.CreateTemplateLogConfig(
        project="<sls-project>",
        logstore="<sls-logstore>",
    ),
    sandbox_config=models.CreateTemplateSandboxConfig(
        image=f"fc-e2b-registry.{REGION}.cr.aliyuncs.com/runtime-v2/base:v0.0.53",
        generation=2,
    ),
)

Verification: The sandbox can access resources in the VPC, but access to Internet addresses times out or is rejected.

Scenario 3: Access the VPC and the Internet over a fixed egress IP address

Configure vpc_config, and disable internet_access. In the VPC, provide an Internet NAT gateway, an EIP, and the corresponding routes and SNAT rules, so that Internet traffic egresses through the specified gateway.

  1. VPC preparations: Configure an Internet NAT gateway for the VPC and associate an EIP with the gateway. For the related vSwitches, configure routes that point to the NAT gateway and add SNAT rules. Make sure that the traffic of the vSwitch that hosts the sandbox can reach the Internet over this egress.

  2. Template configurations: the same parameters as Scenario 2 (internet_access=False + vpc_config).

Verification: Query the egress IP address in the sandbox, for example curl ifconfig.me. The EIP that you configured is returned.

The template build parameters of Scenario 2 and Scenario 3 are the same. The difference is whether the VPC provides an Internet egress. Therefore, after internet_access is disabled, you must still check the network configuration of the VPC to determine whether the sandbox can access the Internet.

FAQ

Can a first-generation template configure a start command and a ready command?

No. If a first-generation template specifies start_command or ready_command, 400 InvalidParameter is returned. To fix a long-running process in a template, use a second-generation template.

Why do all build examples include log configurations?

log_config delivers the logs of the template build period and the sandbox running period to SLS in your account, which helps locate issues during build and runtime verification. During the build, the logs show the output of the start command and the ready command, and the cause of a build failure. During the run, the logs show the output of the processes inside the sandbox. The logs are viewed in the project and Logstore that you configure in the SLS console. Both must be in the same region as Agent Sandbox.

Why can the Internet still be accessed after internet_access is disabled?

internet_access controls only the Internet egress on the platform side. If the VPC that the template connects to already provides an Internet egress (NAT gateway + EIP + SNAT), the sandbox can still access the Internet over that egress. To completely isolate the sandbox from the Internet, check both the template parameters and the network configuration of the VPC.

How do I obtain a fixed Internet egress IP address?

Use the configuration of Scenario 3. On the template side, disable internet_access and configure vpc_config. On the VPC side, provide an Internet NAT gateway and an EIP, and configure the corresponding routes and SNAT rules. Then check whether the egress IP address in the sandbox is the EIP that you configured.

How do I troubleshoot image pull failures, build failures, or start failures?

  1. Use GetTemplate to query status.reason.message, which provides the failure stage and the cause.

  2. View detailed logs in the SLS Logstore configured by log_config.

  3. Troubleshoot by failure stage:

    • Image pull failure: Check that the image address and tag are correct, the credentials have the pull permission, and the pull network is reachable (the VPC association of the ACR EE instance is active, and the outbound direction of the security group allows TCP port 443).

    • Build failure: Check that the image meets the image requirements, such as the linux/amd64 architecture, the /bin/bash path, and /etc/passwd being writable. For a first-generation template, check that the destination repository credentials have the push permission.

    • Start command or ready check failure (second generation): Check that start_command does not exit prematurely, and that ready_command probes the real readiness condition and passes within 5 minutes.