跳到主要内容

DaytonaSandbox

在隔离的 Daytona 云 Sandbox 中执行命令。支持多种运行时、资源配置、卷、快照、流式输出、Sandbox 重连、文件系统挂载(S3、GCS)和网络隔离。有关接口的详细信息,请参阅 WorkspaceSandbox 接口

安装
安装的直接链接

npm install @mastra/daytona

可以通过以下三种方式之一设置 Daytona API 密钥。

export DAYTONA_API_KEY=your-api-key

使用方法
使用方法的直接链接

DaytonaSandbox 添加到 Workspace 并分配给 Agent:

import { Agent } from '@mastra/core/agent'
import { Workspace } from '@mastra/core/workspace'
import { DaytonaSandbox } from '@mastra/daytona'

const workspace = new Workspace({
sandbox: new DaytonaSandbox({
language: 'typescript',
timeout: 120_000,
}),
})

const agent = new Agent({
id: 'code-agent',
name: 'Code Agent',
instructions: 'You are a coding assistant working in this workspace.',
model: 'anthropic/claude-sonnet-4-6',
workspace,
})

const response = await agent.generate(
'Print "Hello, world!" and show the current working directory.',
)

console.log(response.text)
// I'll run both commands simultaneously!
//
// Here are the results:
//
// 1. **Hello, world!** — Successfully printed the message.
// 2. **Current Working Directory** — `/home/daytona`
//
// Both commands ran in parallel and completed successfully!

使用快照
使用快照的直接链接

使用预构建快照可省去环境设置时间:

const workspace = new Workspace({
sandbox: new DaytonaSandbox({
snapshot: 'my-snapshot-id',
timeout: 60_000,
}),
})

使用自定义镜像和资源
使用自定义镜像和资源的直接链接

使用自定义 Docker 镜像并指定资源分配:

const workspace = new Workspace({
sandbox: new DaytonaSandbox({
image: 'node:20-slim',
resources: { cpu: 2, memory: 4, disk: 6 },
language: 'typescript',
}),
})

临时 Sandbox
临时 Sandbox的直接链接

用于一次性任务:Sandbox 停止后会立即删除:

const workspace = new Workspace({
sandbox: new DaytonaSandbox({
ephemeral: true,
language: 'python',
}),
})

流式输出
流式输出的直接链接

通过 onStdoutonStderr 回调实时传输命令输出:

await sandbox.executeCommand('bash', ['-c', 'for i in 1 2 3; do echo "line $i"; sleep 1; done'], {
onStdout: chunk => process.stdout.write(chunk),
onStderr: chunk => process.stderr.write(chunk),
})

两个回调均为可选项,可以独立使用。

重连
重连的直接链接

提供相同的 id 即可重新连接到现有 Sandbox。Sandbox 会恢复运行,并保留其文件和状态:

const sandbox = new DaytonaSandbox({ id: 'my-persistent-sandbox' })

// First session
await sandbox._start()
await sandbox.executeCommand('sh', ['-c', 'echo "session 1" > /tmp/state.txt'])
await sandbox._stop()

// Later — reconnects to the same sandbox
const sandbox2 = new DaytonaSandbox({ id: 'my-persistent-sandbox' })
await sandbox2._start()
const result = await sandbox2.executeCommand('cat', ['/tmp/state.txt'])
console.log(result.stdout) // "session 1"

如果 Sandbox 处于已停止或已归档状态,则会自动重新启动。如果处于失效状态(已销毁、出错),则改为创建一个新的 Sandbox。

文件系统挂载
文件系统挂载的直接链接

将 S3 或 GCS 存储桶挂载为 Sandbox 内的本地目录。

通过 Workspace mounts 配置
通过 Workspace mounts 配置的直接链接

最简单的方式:Sandbox 启动时自动挂载文件系统:

import { Workspace } from '@mastra/core/workspace'
import { DaytonaSandbox } from '@mastra/daytona'
import { GCSFilesystem } from '@mastra/gcs'
import { S3Filesystem } from '@mastra/s3'

const workspace = new Workspace({
mounts: {
'/s3-data': new S3Filesystem({
bucket: process.env.S3_BUCKET!,
region: 'auto',
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
endpoint: process.env.S3_ENDPOINT, // e.g. https://<account-id>.r2.cloudflarestorage.com
}),
'/gcs-data': new GCSFilesystem({
bucket: process.env.GCS_BUCKET!,
projectId: 'my-project-id',
credentials: JSON.parse(process.env.GCS_SERVICE_ACCOUNT_KEY!),
}),
},
sandbox: new DaytonaSandbox({ language: 'python' }),
})

Workspace 启动时,文件系统会自动挂载到指定路径。随后,在 Sandbox 中运行的代码可以像访问本地目录一样访问 /s3-data/gcs-data 中的文件。

通过 sandbox.mount()
via-sandboxmount的直接链接

Sandbox 启动后,可随时手动挂载:

S3
S3的直接链接

import { S3Filesystem } from '@mastra/s3'

await sandbox.mount(
new S3Filesystem({
bucket: process.env.S3_BUCKET!,
region: 'us-east-1',
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
}),
'/data',
)

S3 兼容服务(Cloudflare R2、MinIO)
S3 兼容服务(Cloudflare R2、MinIO)的直接链接

import { S3Filesystem } from '@mastra/s3'

await sandbox.mount(
new S3Filesystem({
bucket: process.env.S3_BUCKET!,
region: 'auto',
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
endpoint: process.env.S3_ENDPOINT, // e.g. https://<account-id>.r2.cloudflarestorage.com
}),
'/data',
)

GCS
GCS的直接链接

import { GCSFilesystem } from '@mastra/gcs'

await sandbox.mount(
new GCSFilesystem({
bucket: process.env.GCS_BUCKET!,
projectId: 'my-project-id',
credentials: JSON.parse(process.env.GCS_SERVICE_ACCOUNT_KEY!),
}),
'/data',
)

网络隔离
网络隔离的直接链接

限制出站网络访问:

const workspace = new Workspace({
sandbox: new DaytonaSandbox({
networkBlockAll: true,
networkAllowList: '10.0.0.0/8,192.168.0.0/16',
}),
})

对于 IP 地址会发生变化的服务(例如包注册表和托管 API),请使用 domainAllowList

const workspace = new Workspace({
sandbox: new DaytonaSandbox({
networkBlockAll: true,
domainAllowList: 'registry.npmjs.org,*.githubusercontent.com',
}),
})

两个允许列表都在创建 Sandbox 时应用,并由 clone() 保留。要在 Sandbox 启动后更改策略,请使用底层 Daytona Sandbox:

await sandbox.instance.updateNetworkSettings({
domainAllowList: 'api.example.com',
})

构造函数参数
构造函数参数的直接链接

id?:

string
= 自动生成
此 Sandbox 实例的唯一标识符。

apiKey?:

string
用于身份验证的 Daytona API 密钥。未提供时使用 DAYTONA_API_KEY 环境变量。

apiUrl?:

string
Daytona API 端点。未提供时使用 DAYTONA_API_URL 环境变量。

target?:

string
Runner 区域。未提供时使用 DAYTONA_TARGET 环境变量。

timeout?:

number
= 300000(5 分钟)
默认执行超时时间(毫秒)。

language?:

'typescript' | 'javascript' | 'python'
= 'typescript'
Sandbox 的运行时语言。

snapshot?:

string
创建 Sandbox 所依据的预构建快照 ID。优先级高于 image。

image?:

string
用于创建 Sandbox 的 Docker 镜像。设置后触发基于镜像的创建方式。可与 resources 结合使用。设置 snapshot 时忽略此项。

resources?:

{ cpu?: number; memory?: number; disk?: number }
Sandbox 的资源分配(CPU 核心数、以 GiB 为单位的内存、以 GiB 为单位的磁盘)。仅在设置 image 时使用。

env?:

Record<string, string>
= {}
要在 Sandbox 中设置的环境变量。

labels?:

Record<string, string>
= {}
自定义元数据标签。

name?:

string
= Sandbox id
Sandbox 显示名称。

user?:

string
= 'daytona'
运行命令所使用的操作系统用户。

public?:

boolean
= false
将端口预览设为公开。

ephemeral?:

boolean
= false
停止时立即删除 Sandbox。

autoStopInterval?:

number
= 15
自动停止间隔(分钟)。设置为 0 可禁用。

autoArchiveInterval?:

number
= 7 天
自动归档间隔(分钟)。设置为 0 可使用最长间隔(7 天)。

autoDeleteInterval?:

number
= 已禁用
自动删除间隔(分钟)。负值会禁用自动删除。设置为 0 可在停止时删除。

volumes?:

Array<{ volumeId: string; mountPath: string }>
创建 Sandbox 时要附加的 Daytona 卷。

networkBlockAll?:

boolean
= false
阻止 Sandbox 的所有出站网络访问。

networkAllowList?:

string
限制网络访问时,以逗号分隔的允许 CIDR 地址列表。

domainAllowList?:

string
限制网络访问时,以逗号分隔的允许域名列表。支持通配符,例如 *.githubusercontent.com。对于 IP 地址会变化的服务,请使用此项而不是 networkAllowList

属性
属性的直接链接

id:

string
Sandbox 实例标识符。

name:

string
Provider 名称('DaytonaSandbox')。

provider:

string
Provider 标识符('daytona')。

status:

ProviderStatus
'pending' | 'initializing' | 'ready' | 'stopped' | 'destroyed' | 'error'

instance:

Sandbox
底层 Daytona Sandbox 实例。如果 Sandbox 尚未启动,则抛出 SandboxNotReadyError。

processes:

DaytonaProcessManager
后台进程管理器。请参阅 SandboxProcessManager 参考文档

后台进程
后台进程的直接链接

DaytonaSandbox 包含用于生成和管理后台进程的内置进程管理器。进程使用基于会话的命令执行方式在 Daytona 云 Sandbox 中运行。

const sandbox = new DaytonaSandbox({ language: 'typescript' })
await sandbox.start()

// Spawn a background process
const handle = await sandbox.processes.spawn('node server.js', {
env: { PORT: '3000' },
onStdout: data => console.log(data),
})

// Interact with the process
console.log(handle.stdout)
await handle.sendStdin('input\n')
await handle.kill()

有关完整 API,请参阅 SandboxProcessManager 参考文档

挂载云存储
挂载云存储的直接链接

Daytona Sandbox 可以挂载 S3 或 GCS 存储桶,使云存储能以 Sandbox 内的本地目录形式访问。这适用于:

  • 处理存储在云存储桶中的大型数据集
  • 将输出文件直接写入云存储
  • 在不同 Sandbox 会话之间共享数据

有关使用示例,请参阅文件系统挂载

Daytona Sandbox 使用 FUSE(Filesystem in Userspace)挂载云存储:

如果 Sandbox 镜像中尚未安装所需的 FUSE Tool,则会在挂载时自动安装。

S3 环境变量
S3 环境变量的直接链接

变量说明
S3_BUCKET存储桶名称
S3_REGIONAWS 区域;R2/MinIO 使用 auto
S3_ACCESS_KEY_ID访问密钥 ID
S3_SECRET_ACCESS_KEY机密访问密钥
S3_ENDPOINT端点 URL(仅适用于 S3 兼容服务)

GCS 环境变量
GCS 环境变量的直接链接

变量说明
GCS_BUCKET存储桶名称
GCS_SERVICE_ACCOUNT_KEY服务账号密钥 JSON(完整 JSON 字符串,而不是路径)

使用快照缩短冷启动延迟
使用快照缩短冷启动延迟的直接链接

默认情况下,s3fsgcsfuse 会在首次挂载时通过 apt 安装,这会增加启动时间。要消除这部分延迟,请将它们预先烘焙到 Daytona 快照中,并通过 snapshot 选项传入快照名称。

选项 1:声明式镜像构建

import { Daytona, Image } from '@daytonaio/sdk'

const template = Image.base('daytonaio/sandbox')
.runCommands('sudo apt-get update -qq')
.runCommands('sudo apt-get install -y s3fs')
// gcsfuse requires the Google Cloud apt repository
.runCommands(
'sudo mkdir -p /etc/apt/keyrings && ' +
'curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg -o /tmp/gcsfuse-key.gpg && ' +
'sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/gcsfuse.gpg /tmp/gcsfuse-key.gpg && ' +
// Use gcsfuse-jammy for Ubuntu, gcsfuse-bookworm for Debian
'echo "deb [signed-by=/etc/apt/keyrings/gcsfuse.gpg] https://packages.cloud.google.com/apt gcsfuse-jammy main" | sudo tee /etc/apt/sources.list.d/gcsfuse.list',
)
.runCommands('sudo apt-get update -qq && sudo apt-get install -y gcsfuse')

const daytona = new Daytona()

await daytona.snapshot.create(
{
name: 'cloud-fs-mounting',
image: template,
},
{ onLogs: console.log },
)

选项 2:Dockerfile: 使用 Image.fromDockerfile()

FROM daytonaio/sandbox
RUN sudo apt-get update -qq
RUN sudo apt-get install -y s3fs
# Use gcsfuse-jammy for Ubuntu, gcsfuse-bookworm for Debian
RUN sudo mkdir -p /etc/apt/keyrings && curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg -o /tmp/gcsfuse-key.gpg && sudo gpg --batch --yes --dearmor -o /etc/apt/keyrings/gcsfuse.gpg /tmp/gcsfuse-key.gpg && echo "deb [signed-by=/etc/apt/keyrings/gcsfuse.gpg] https://packages.cloud.google.com/apt gcsfuse-jammy main" | sudo tee /etc/apt/sources.list.d/gcsfuse.list
RUN sudo apt-get update -qq && sudo apt-get install -y gcsfuse
import { Daytona, Image } from '@daytonaio/sdk'

const daytona = new Daytona()

await daytona.snapshot.create(
{
name: 'cloud-fs-mounting',
image: Image.fromDockerfile('./Dockerfile'),
},
{ onLogs: console.log },
)

然后在 Sandbox 配置中使用快照名称:

const workspace = new Workspace({
mounts: {
'/s3-data': new S3Filesystem({/* ... */}),
'/gcs-data': new GCSFilesystem({/* ... */}),
},
sandbox: new DaytonaSandbox({ snapshot: 'cloud-fs-mounting' }),
})

直接访问 SDK
直接访问 SDK的直接链接

访问底层 Daytona Sandbox 实例,以执行 WorkspaceSandbox 接口未公开的文件系统、git 和其他操作:

const daytonaSandbox = sandbox.instance

// Upload a file
await daytonaSandbox.fs.uploadFile(Buffer.from('hello'), '/tmp/hello.txt')

// Run git operations
await daytonaSandbox.git.clone('https://github.com/org/repo', '/workspace/repo')

如果 Sandbox 尚未启动,instance getter 会抛出 SandboxNotReadyError

Sandbox 创建模式
Sandbox 创建模式的直接链接

DaytonaSandbox 根据提供的选项选择创建模式:

选项创建模式
设置 snapshot基于快照(snapshot 优先于 image)
设置 image(未设置 snapshot)基于镜像(可选用 resources
两者均未设置默认基于快照

仅当设置 image 时才会应用资源。传入 resources 而不传入 image 不会产生任何效果。