跳至主要內容

DaytonaSandbox

在隔離的 Daytona 雲端 Sandbox 中執行指令。支援多種執行環境、資源設定、儲存卷、快照、串流輸出、Sandbox 重新連線、檔案系統掛載(S3、GCS)及網絡隔離。介面詳情請參閱 WorkspaceSandbox 介面

安裝
安裝 的直接連結

npm install @mastra/daytona

使用以下三種方式之一設定 Daytona API key。

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 callback 即時串流傳送指令輸出:

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),
})

兩個 callback 均為選填,亦可獨立使用。

重新連線
重新連線 的直接連結

提供相同的 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 bucket 掛載為 Sandbox 內的本機目錄。

透過 Workspace 掛載設定
透過 Workspace 掛載設定 的直接連結

最簡單的方法是在 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 位址會變更的服務(例如套件 registry 及託管 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 instance 的唯一識別碼。

apiKey?:

string
用於驗證的 Daytona API key。未設定時會改用 DAYTONA_API_KEY 環境變數。

apiUrl?:

string
Daytona API endpoint。未設定時會改用 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 為單位的記憶體及磁碟)。只會在設定 image 時使用。

env?:

Record<string, string>
= {}
要在 Sandbox 中設定的環境變數。

labels?:

Record<string, string>
= {}
自訂 metadata 標籤。

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
限制網絡存取時允許使用的 domain 清單,以逗號分隔。支援萬用字元,例如 *.githubusercontent.com。對於 IP 位址會變更的服務,請使用此項而非 networkAllowList

屬性
屬性 的直接連結

id:

string
Sandbox instance 識別碼。

name:

string
Provider 名稱('DaytonaSandbox')。

provider:

string
Provider 識別碼('daytona')。

status:

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

instance:

Sandbox
底層 Daytona Sandbox instance。如果 Sandbox 尚未啟動,便會拋出 SandboxNotReadyError。

processes:

DaytonaProcessManager
背景 process manager。請參閱 SandboxProcessManager 參考

背景 process
背景 process 的直接連結

DaytonaSandbox 內置 process manager,可建立及管理背景 process。Process 會使用以 session 為基礎的指令執行方式,在 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 bucket,讓 Sandbox 能夠以本機目錄的形式存取雲端儲存空間。這適合用於:

  • 處理儲存在雲端 bucket 的大型數據集
  • 將輸出檔案直接寫入雲端儲存空間
  • 在不同 Sandbox session 之間共用數據

使用範例請參閱掛載檔案系統

Daytona Sandbox 使用 FUSE(Filesystem in Userspace)掛載雲端儲存空間:

掛載時,如果 Sandbox 映像檔尚未包含所需的 FUSE 工具,系統便會自動安裝。

S3 環境變數
S3 環境變數 的直接連結

變數說明
S3_BUCKETBucket 名稱
S3_REGIONAWS 區域;R2/MinIO 使用 auto
S3_ACCESS_KEY_IDAccess key ID
S3_SECRET_ACCESS_KEYSecret access key
S3_ENDPOINTEndpoint URL(只適用於 S3 相容服務)

GCS 環境變數
GCS 環境變數 的直接連結

變數說明
GCS_BUCKETBucket 名稱
GCS_SERVICE_ACCOUNT_KEYService account key JSON(完整 JSON 字串,而非路徑)

使用快照降低冷啟動延遲
使用快照降低冷啟動延遲 的直接連結

預設情況下,首次掛載時會透過 apt 安裝 s3fsgcsfuse,因而增加啟動時間。要消除這段時間,可預先將兩者加入 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 instance,以執行 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 並不會產生任何效果。