# Use the sandbox to quickly create your remote development environment

![overview](https://cdnv2.udelivrs.com/2026/06/4c4d712338615dd562ace934d6cd20d2_1781578748732.png)

Want to quickly set up an out-of-the-box remote development environment? UCloud Sandbox can help you! Building the development environment in a sandbox has the following benefits:

- Not limited to local environment and resources, quickly start a complete development environment in a few seconds.
- Access the development environment through our domain name, there is no need to purchase an external IP yourself, and the data is transmitted securely.
- Execute untrusted code generated by AI with confidence.
- During the vibe coding process, AI can only read the code in the restricted sandbox and cannot steal sensitive data on the real machine.
- When you don’t want to use it, you can pause the running sandbox and retain all data (including memory). Next time you want to use it, you can automatically start it by accessing the service, which greatly saves costs.

Below, we will take you step by step to demonstrate how to use the sandbox to start your own remote development environment.

## Prepare

We will use Python to build a development environment. First, create a project and install the corresponding dependencies:

```bash
mkdir codeagent
cd codeagent
python3 -m venv venv
source ./venv/bin/activate
pip3 install ucloud-sandbox
```

Set environment variables to connect to the sandbox service we provide:

```bash
export UCLOUD_SANDBOX_API_KEY='<api-key>'
```

API Key can be obtained from [Star Map Platform Key Management] (https://astraflow.ucloud.cn/modelverse/api-keys).

## Build codeagent template

You need to build a template to run the code server for remote development, here is an example:

```python
from ucloud_sandbox import Template, default_build_logger, wait_for_port

# code-server login password (please change it to your own strong password)
CODE_SERVER_PASSWORD = "ucloud123"

template = (
    Template()
    .from_ubuntu_image("22.04")
    .run_cmd("curl -fsSL https://code-server.dev/install.sh | sh")
    # Pre-installed Claude Code and Codex plug-ins (both in the default Open VSX store of code-server)
    # Install to the extension directory of the runtime user user to ensure that it can be loaded directly after startup
    .run_cmd(
        "code-server "
        "--extensions-dir /home/user/.local/share/code-server/extensions "
        "--install-extension anthropic.claude-code "
        "--install-extension openai.chatgpt"
    )
    #Create default working directory
    .run_cmd("mkdir -p /home/user/app")
    # Close the Workspace Trust pop-up window (automatically trust all folders)
    .run_cmd(
        "mkdir -p /home/user/.local/share/code-server/User && "
        "echo '{\"security.workspace.trust.enabled\": false}' "
        "> /home/user/.local/share/code-server/User/settings.json"
    )
    # Inject the password through environment variables, and use --auth password to log in with the password
    .set_envs({
        "PASSWORD": CODE_SERVER_PASSWORD,
    })
    # When starting the sandbox, pull up code-server and bind 0.0.0.0:8080 so that the external network can access it through a proxy
    # /home/user/app at the end is the working directory opened by code-server by default
    .set_start_cmd(
        "code-server --bind-addr 0.0.0.0:8080 --auth password --disable-telemetry /home/user/app",
        wait_for_port(8080),
    )
)

Template.build(
    template,
    alias="codeagent-test", # Template alias (required)
    cpu_count=4, # Number of CPU cores
    memory_mb=4096, # Memory (MB)
    on_build_logs=default_build_logger(min_level='debug'),
)
```

Execute the above code using python to build the template:

```bash
python3 ./template.py
```

You should be able to see the template build log. When the words `Build finished` appear, it means the build has been completed.

You can customize the above build process, add some of your own configurations and scripts, or install some development environments through `run_cmd`, such as `C/C++`, `Java`, `Go`, `Rust` and other programming environments, which can be installed during the above process of building the template.

## Start the remote development environment

In order to ensure that our development environment can always be retained, when starting the sandbox, we need to configure `autoresume`. This parameter allows the sandbox to be automatically suspended after timeout. After that, it can be automatically restored by simply accessing the URL of the development environment. There is no need to manually restore the sandbox.

Through this mechanism, it is possible to:

- When the development environment has not been operated for a long time, it will be automatically suspended to save background resource usage and costs. All memory and system disk data are retained.
- As long as the development environment is accessed, even if it is in a suspended state, it can be automatically resumed and can be restored to the last working state immediately.

You can think of it as a computer configured with automatic hibernation. It will automatically hibernate when you are not working for a long time, and will immediately return to the last working state as soon as you start working.

The following code starts a remote development environment:

```python
import argparse
import json
import os

from ucloud_sandbox import Sandbox

# Parse command line parameters: git warehouse address
parser = argparse.ArgumentParser(description="Start codeagent sandbox and clone code")
parser.add_argument("git_url", help="The git warehouse address to be cloned to the sandbox working directory")
args = parser.parse_args()

# Read API Key from local environment variables, used to configure Claude Code / Codex in the sandbox
api_key = os.environ.get("E2B_API_KEY")
if not api_key:
    parser.error("Environment variable E2B_API_KEY is not set")

# Working directory within the sandbox
REMOTE_WORKDIR = "/home/user/app"

sandbox = Sandbox.create(
    template="codeagent-test",

    # Sandbox timeout, 10 minutes, after this time the sandbox will be suspended
    timeout=10 * 60,

    # Set autoresume, the sandbox will automatically pause when it times out, and will automatically resume when there is a network request.
    lifecycle={
        "on_timeout": "pause",
        "auto_resume": True,
    },
)

print(f'Sandbox id: {sandbox.sandbox_id}')

# git clone in the sandbox and replace the working directory
# First clear the existing working directory, and then clone to the directory (git clone requires the target directory to be empty)
print(f'Cloning {args.git_url} -> {REMOTE_WORKDIR} ...')
sandbox.commands.run(f"rm -rf {REMOTE_WORKDIR}")
sandbox.commands.run(f"git clone {args.git_url} {REMOTE_WORKDIR}")

print(f'Code cloned to {REMOTE_WORKDIR}')

# Configure Claude Code: write ~/.claude/settings.json
print('Configuring Claude Code ...')
claude_settings = {
    "env": {
        "ANTHROPIC_AUTH_TOKEN": api_key,
        "ANTHROPIC_BASE_URL": "https://api.modelverse.cn",
        "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
    },
    "effortLevel": "max",
}
sandbox.commands.run("mkdir -p /home/user/.claude")
sandbox.files.write(
    "/home/user/.claude/settings.json",
    json.dumps(claude_settings, indent=2),
)

# Configure Codex: write ~/.codex/config.toml and ~/.codex/auth.json
print('Configuring Codex ...')
codex_config = """\
model_provider = "ucloud"
model = "gpt-5.5"
model_reasoning_effort = "xhigh"

[model_providers.ucloud]
name = "ucloud"
base_url = "https://api.modelverse.cn/v1"
wire_api = "responses"
requires_openai_auth = true
"""
codex_auth = {"OPENAI_API_KEY": api_key}
sandbox.commands.run("mkdir -p /home/user/.codex")
sandbox.files.write("/home/user/.codex/config.toml", codex_config)
sandbox.files.write("/home/user/.codex/auth.json", json.dumps(codex_auth, indent=2))

print(f'Code agent address: {sandbox.get_host(8080)}')
```

The above script will start a remote development environment, and then use git clone a project to the development environment.

Usage example:

```bash
python3 ./start.py https://github.com/ucloud/ucloud-sandbox-sdk-python.git
```

The script will have output similar to the following:

```text
Sandbox id: <sandbox-id>
Cloning https://github.com/ucloud/ucloud-sandbox-sdk-python.git -> /home/user/app ...
Code cloned to /home/user/app
Code agent address: 8080-<sandbox-id>.cn-wlcb.sandbox.ucloudai.com
```

Open `8080-<sandbox-id>.cn-wlcb.sandbox.ucloudai.com` in the browser to see the remote development environment.

The above script will read your API Key and generate Claude Code and Codex configuration so that Claude Code and Codex can directly connect to [modelverse](https://astraflow.ucloud.cn/modelverse/playground). If you do not need them to connect to modelverse by default, or need to use other models, you can modify or delete the corresponding code.

## Use Claude Code or Codex

If you use the development environment started by my sample code above, the environment has Claude Code and Codex installed by default, and has been connected to the ModelVerse by default using the API Key of the sandbox you created.

You can start happily Vibe coding directly:

![claude code](https://cdnv2.udelivrs.com/2026/06/a11471f090bb0335ac9a084255505357_1781578748719.png)

## Pause the development environment

Generally speaking, when the sandbox times out, the development environment will be paused by default. You do not need to pause it manually. However, you can also manually pause the sandbox through code:

```python
import argparse

from ucloud_sandbox import Sandbox

parser = argparse.ArgumentParser(description="Pause a sandbox")
parser.add_argument("sandbox_id", help="Sandbox ID to be paused")
args = parser.parse_args()

sandbox = Sandbox.connect(args.sandbox_id)

sandbox.pause()

print(f'Sandbox {sandbox.sandbox_id} has been paused')
```

## Destroy the development environment

When you no longer need to use the sandbox, you can use the following code to destroy it:

```python
import argparse

from ucloud_sandbox import Sandbox

parser = argparse.ArgumentParser(description="Destroy a sandbox")
parser.add_argument("sandbox_id", help="Sandbox ID to be destroyed")
args = parser.parse_args()

sandbox = Sandbox.connect(args.sandbox_id)

sandbox.kill()

print(f'Sandbox {sandbox.sandbox_id} has been destroyed')
```

## Snapshot

If you have made some changes in your development environment, such as installing some plug-ins and making some special configurations, and you want to keep these configurations permanently so that you can use the same configurations to quickly create the same development environment in the future, you can save the sandbox as a snapshot, and you can use the snapshot to quickly start a new sandbox in the future.

Use the following code to create a snapshot:

```python
import argparse

from ucloud_sandbox import Sandbox

parser = argparse.ArgumentParser(description="Create a snapshot")
parser.add_argument("sandbox_id", help="Sandbox ID to create snapshot")
args = parser.parse_args()

sandbox = Sandbox.connect(args.sandbox_id)

snapshot = sandbox.create_snapshot()
print('Snapshot ID:', snapshot.snapshot_id)
```

Execute code:

```bash
python3 ./create-snapshot.py <sandbox-id>
```

You'll see the snapshot id printed:

```text
Snapshot ID: <snapshot-id>
```

Use the following code to create a new sandbox with a snapshot:

```python
import argparse

from ucloud_sandbox import Sandbox

parser = argparse.ArgumentParser(description="Create a sandbox from a snapshot")
parser.add_argument("snapshot_id", help="snapshot ID")
args = parser.parse_args()

sandbox = Sandbox.create(args.snapshot_id)

print(f'Sandbox id: {sandbox.sandbox_id}')
print(f'Code agent address: {sandbox.get_host(8080)}')
```

In this way, you can achieve an effect similar to **Sandbox Clone**.