跳至主要內容

DaytonaSandbox

在隔離的 Daytona 雲端 Sandbox 中執行指令。支援多種執行階段、資源設定、Volume、快照、串流輸出、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 Bucket 掛載為 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',
}),
})

對套件登錄檔與託管 API 這類 IP 位址會變動的服務,請使用 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
= Auto-generated
此 Sandbox 執行個體的唯一識別碼。

apiKey?:

string
用於驗證的 Daytona API 金鑰。若未提供,則使用 DAYTONA_API_KEY 環境變數。

apiUrl?:

string
Daytona API 端點。若未提供,則使用 DAYTONA_API_URL 環境變數。

target?:

string
Runner 區域。若未提供,則使用 DAYTONA_TARGET 環境變數。

timeout?:

number
= 300000 (5 minutes)
預設執行逾時時間,單位為毫秒。

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>
= {}
自訂中繼資料標籤。

name?:

string
= Sandbox id
Sandbox 顯示名稱。

user?:

string
= 'daytona'
執行指令時使用的作業系統使用者。

public?:

boolean
= false
公開連接埠預覽。

ephemeral?:

boolean
= false
停止時立即刪除 Sandbox。

autoStopInterval?:

number
= 15
自動停止間隔,單位為分鐘。設為 0 可停用。

autoArchiveInterval?:

number
= 7 days
自動封存間隔,單位為分鐘。設為 0 可使用最大間隔(7 天)。

autoDeleteInterval?:

number
= disabled
自動刪除間隔,單位為分鐘。負值會停用自動刪除;設為 0 則在停止時刪除。

volumes?:

Array<{ volumeId: string; mountPath: string }>
建立 Sandbox 時要附加的 Daytona Volume。

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 Bucket,讓雲端儲存空間可作為 Sandbox 內的本機目錄存取。這適用於:

  • 處理儲存在雲端 Bucket 中的大型資料集
  • 將輸出檔案直接寫入雲端儲存空間
  • 在 Sandbox 工作階段之間分享資料

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

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

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

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

變數說明
S3_BUCKETBucket 名稱
S3_REGIONAWS 區域;R2/MinIO 使用 auto
S3_ACCESS_KEY_ID存取金鑰 ID
S3_SECRET_ACCESS_KEY私密存取金鑰
S3_ENDPOINT端點 URL(僅限 S3 相容服務)

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

變數說明
GCS_BUCKETBucket 名稱
GCS_SERVICE_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 執行個體,以執行檔案系統、git 及其他未透過 WorkspaceSandbox 介面公開的操作:

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 不會有任何效果。