DaytonaSandbox
Exécute des commandes dans des Sandboxes cloud Daytona isolées. Prend en charge plusieurs environnements d'exécution, la configuration des ressources, les volumes, les snapshots, la sortie en streaming, la reconnexion aux Sandboxes, le montage de systèmes de fichiers (S3, GCS) et l'isolation réseau. Pour plus de détails sur l'interface, consultez l'interface WorkspaceSandbox.
InstallationLien direct vers Installation
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/daytona
pnpm add @mastra/daytona
yarn add @mastra/daytona
bun add @mastra/daytona
Définissez votre clé d'API Daytona de l'une des trois manières suivantes.
- Export du shell
- Fichier .env
- Constructeur
export DAYTONA_API_KEY=your-api-key
DAYTONA_API_KEY=your-api-key
new DaytonaSandbox({ apiKey: 'your-api-key' })
UtilisationLien direct vers Utilisation
Ajoutez une DaytonaSandbox à un Workspace et attribuez-la à un 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!
Avec un snapshotLien direct vers Avec un snapshot
Utilisez un snapshot préconstruit pour éviter le temps de configuration de l'environnement :
const workspace = new Workspace({
sandbox: new DaytonaSandbox({
snapshot: 'my-snapshot-id',
timeout: 60_000,
}),
})
Image personnalisée avec des ressourcesLien direct vers Image personnalisée avec des ressources
Utilisez une image Docker personnalisée avec une allocation de ressources précise :
const workspace = new Workspace({
sandbox: new DaytonaSandbox({
image: 'node:20-slim',
resources: { cpu: 2, memory: 4, disk: 6 },
language: 'typescript',
}),
})
Sandbox éphémèreLien direct vers Sandbox éphémère
Pour les tâches ponctuelles, la Sandbox est supprimée dès son arrêt :
const workspace = new Workspace({
sandbox: new DaytonaSandbox({
ephemeral: true,
language: 'python',
}),
})
Sortie en streamingLien direct vers Sortie en streaming
Diffusez la sortie des commandes en temps réel au moyen des callbacks onStdout et onStderr :
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),
})
Les deux callbacks sont facultatifs et peuvent être utilisés séparément.
ReconnexionLien direct vers Reconnexion
Reconnectez-vous à une Sandbox existante en fournissant le même id. La Sandbox reprend avec ses fichiers et son état intacts :
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"
Si la Sandbox est arrêtée ou archivée, elle redémarre automatiquement. Si elle est définitivement inactive (détruite ou en erreur), une nouvelle Sandbox est créée à la place.
Montage de systèmes de fichiersLien direct vers Montage de systèmes de fichiers
Montez des buckets S3 ou GCS comme répertoires locaux dans la Sandbox.
Via la configuration des montages du WorkspaceLien direct vers Via la configuration des montages du Workspace
La méthode la plus simple : les systèmes de fichiers sont montés automatiquement au démarrage de la 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' }),
})
Au démarrage du Workspace, les systèmes de fichiers sont automatiquement montés aux chemins indiqués. Le code exécuté dans la Sandbox peut alors accéder aux fichiers de /s3-data et /gcs-data comme s'il s'agissait de répertoires locaux.
Via sandbox.mount()Lien direct vers via-sandboxmount
Effectuez un montage manuel à tout moment après le démarrage de la Sandbox :
S3Lien direct vers 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',
)
Compatible S3 (Cloudflare R2, MinIO)Lien direct vers Compatible 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',
)
GCSLien direct vers 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',
)
Isolation réseauLien direct vers Isolation réseau
Limitez l'accès réseau sortant :
const workspace = new Workspace({
sandbox: new DaytonaSandbox({
networkBlockAll: true,
networkAllowList: '10.0.0.0/8,192.168.0.0/16',
}),
})
Utilisez domainAllowList pour les services dont les adresses IP changent, tels que les registres de packages et les API hébergées :
const workspace = new Workspace({
sandbox: new DaytonaSandbox({
networkBlockAll: true,
domainAllowList: 'registry.npmjs.org,*.githubusercontent.com',
}),
})
Les deux listes d'autorisation sont appliquées lors de la création de la Sandbox et conservées par clone(). Pour modifier la politique après le démarrage de la Sandbox, utilisez la Sandbox Daytona sous-jacente :
await sandbox.instance.updateNetworkSettings({
domainAllowList: 'api.example.com',
})
Paramètres du constructeurLien direct vers Paramètres du constructeur
id?:
apiKey?:
apiUrl?:
target?:
timeout?:
language?:
snapshot?:
image?:
resources?:
env?:
labels?:
name?:
user?:
public?:
ephemeral?:
autoStopInterval?:
autoArchiveInterval?:
autoDeleteInterval?:
volumes?:
networkBlockAll?:
networkAllowList?:
domainAllowList?:
*.githubusercontent.com. Utilisez cette option à la place de networkAllowList pour les services dont les adresses IP changent.PropriétésLien direct vers Propriétés
id:
name:
provider:
status:
instance:
processes:
Processus en arrière-planLien direct vers Processus en arrière-plan
DaytonaSandbox comprend un gestionnaire de processus intégré permettant de lancer et de gérer des processus en arrière-plan. Ceux-ci s'exécutent dans la Sandbox cloud Daytona au moyen d'une exécution de commandes fondée sur les sessions.
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()
Consultez la référence de SandboxProcessManager pour découvrir l'API complète.
Montage du stockage cloudLien direct vers Montage du stockage cloud
Les Sandboxes Daytona peuvent monter des buckets S3 ou GCS, rendant le stockage cloud accessible comme des répertoires locaux dans la Sandbox. Cette fonctionnalité permet notamment de :
- Traiter de grands jeux de données stockés dans des buckets cloud
- Écrire les fichiers de sortie directement dans le stockage cloud
- Partager des données entre les sessions de Sandbox
Pour consulter des exemples d'utilisation, reportez-vous au montage de systèmes de fichiers.
Les Sandboxes Daytona utilisent FUSE (Filesystem in Userspace) pour monter le stockage cloud :
Les Tools FUSE nécessaires sont installés automatiquement lors du montage s'ils ne figurent pas déjà dans l'image de la Sandbox.
Variables d'environnement S3Lien direct vers Variables d'environnement S3
| Variable | Description |
|---|---|
S3_BUCKET | Nom du bucket |
S3_REGION | Région AWS ou auto pour R2/MinIO |
S3_ACCESS_KEY_ID | Identifiant de la clé d'accès |
S3_SECRET_ACCESS_KEY | Clé d'accès secrète |
S3_ENDPOINT | URL de l'endpoint (compatible S3 uniquement) |
Variables d'environnement GCSLien direct vers Variables d'environnement GCS
| Variable | Description |
|---|---|
GCS_BUCKET | Nom du bucket |
GCS_SERVICE_ACCOUNT_KEY | Clé JSON du compte de service (chaîne JSON complète, pas un chemin) |
Réduction de la latence du démarrage à froid avec un snapshotLien direct vers Réduction de la latence du démarrage à froid avec un snapshot
Par défaut, s3fs et gcsfuse sont installés via apt lors du premier montage, ce qui allonge le démarrage. Pour éviter ce délai, préinstallez-les dans un snapshot Daytona et transmettez le nom de celui-ci au moyen de l'option snapshot.
Option 1 : build déclaratif de l'image
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 },
)
Option 2 : Dockerfile : utilisez 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 },
)
Utilisez ensuite le nom du snapshot dans la configuration de votre Sandbox :
const workspace = new Workspace({
mounts: {
'/s3-data': new S3Filesystem({/* ... */}),
'/gcs-data': new GCSFilesystem({/* ... */}),
},
sandbox: new DaytonaSandbox({ snapshot: 'cloud-fs-mounting' }),
})
Accès direct au SDKLien direct vers Accès direct au SDK
Accédez à l'instance Daytona Sandbox sous-jacente pour les opérations sur le système de fichiers, git et les autres opérations non exposées par l'interface 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')
Le getter instance lève SandboxNotReadyError si la Sandbox n'a pas encore été démarrée.
Modes de création de la SandboxLien direct vers Modes de création de la Sandbox
DaytonaSandbox sélectionne un mode de création selon les options fournies :
| Options | Mode de création |
|---|---|
snapshot défini | Fondé sur un snapshot (le snapshot est prioritaire sur l'image) |
image défini (sans snapshot) | Fondé sur une image (éventuellement avec resources) |
| Aucun des deux | Fondé par défaut sur un snapshot |
Les ressources sont appliquées uniquement lorsque image est défini. Transmettre resources sans image reste sans effet.