# Daytona Documentation v0.0.0-dev
# Generated on: 2025-10-31
title: API Keys
Daytona API keys are used to authenticate requests to the [Daytona API](/docs/en/tools/api). You can view, create, or delete your API Keys on the [API Keys](https://app.daytona.io/dashboard/keys) page.
## Creating an API key
You can obtain an API key from the Daytona platform:
1. Navigate to [API Keys](https://app.daytona.io/dashboard/keys), on the [Daytona Dashboard](https://app.daytona.io/dashboard/).
2. Click the **`Create Key`** button.
3. In the open modal, create and copy a new key to your clipboard.
To use an API key in your application, set the `DAYTONA_API_KEY` environment variable as described on the [Configuration](/docs/en/configuration) page.
## Permissions & Scopes
When creating a new API Key, you can select the specific permissions (scopes) it should have. Scopes control what actions the key can perform. Grant only the scopes you need for each key.
Below is a list of available scopes and their descriptions:
| Resource | Scope | Description |
|-------------|----------------------|--------------------------------------|
| Sandboxes | `write:sandboxes` | Create/modify sandboxes |
| | `delete:sandboxes` | Delete sandboxes |
| Snapshots | `write:snapshots` | Create/modify snapshots |
| | `delete:snapshots` | Delete snapshots |
| Registries | `write:registries` | Create/modify registries |
| | `delete:registries` | Delete registries |
| Volumes | `read:volumes` | View volumes |
| | `write:volumes` | Create/modify volumes |
| | `delete:volumes` | Delete volumes |
| Audit | `read:audit_logs` | View audit logs |
title: Audit Logs
description: View and monitor all user actions across your Daytona organization.
Daytona Audit Logs provide a detailed record of user and system activity across your organization. Use this feature to track sandbox lifecycle events, user access, system changes, and more.
You can access Audit Logs from the [Dashboard](https://app.daytona.io/dashboard/audit-logs).
## Prerequisites
Audit logs are available to:
- **Admins** - Full access to all audit logs
- **Members** - Access only if they have audit log permissions
Contact your organization admin if you cannot access audit logs.
## Real-Time Updates
Enable the **Real-Time Updates** toggle in the top-right corner of the Audit Logs page to automatically refresh logs as new events occur.
## Log Structure
Each log entry includes the following columns:
| Field | Description |
|---------- |----------------------------------------|
| **Time** | Timestamp of when the action occurred (UTC) |
| **User** | Email of the user who performed action |
| **Action**| Operation executed |
| **Target**| Resource type affected |
| **Outcome**| Result status code and message |
### Example
```text
Time: 5h ago (7/31/2025, 8:15:27 AM)
User: janedoe@acme.com
Action: create
Target: sandbox (ID: 10f249ad-...)
Outcome: Success (200)
```
## Use Cases
- **Security audits**: Monitor for unauthorized access or sandbox misuse
- **Debugging**: Understand sandbox lifecycle issues (e.g. failed starts)
- **Compliance Export**: Export logs for internal or external audits (Coming soon)
## Actions
Below is the complete list of actions logged by Daytona:
```text
create, read, update, delete, login,
set_default, update_access, update_quota,
suspend, unsuspend, accept, decline,
link_account, unlink_account, leave_organization,
regenerate_key_pair, update_scheduling,
start, stop, replace_labels, create_backup,
update_public_status, set_auto_stop_interval,
set_auto_archive_interval, set_auto_delete_interval, archive,
get_port_preview_url, set_general_status, activate, deactivate,
update_network_settings, get_webhook_app_portal_access,
send_webhook_message, initialize_webhooks,
update_sandbox_default_limited_network_egress,
create_ssh_access, revoke_ssh_access,
toolbox_delete_file, toolbox_download_file, toolbox_create_folder,
toolbox_move_file, toolbox_set_file_permissions, toolbox_replace_in_files,
toolbox_upload_file, toolbox_bulk_upload_files,
toolbox_git_add_files, toolbox_git_create_branch, toolbox_git_delete_branch,
toolbox_git_clone_repository, toolbox_git_commit_changes,
toolbox_git_pull_changes, toolbox_git_push_changes,
toolbox_git_checkout_branch, toolbox_execute_command,
toolbox_create_session, toolbox_session_execute_command,
toolbox_delete_session, toolbox_computer_use_start,
toolbox_computer_use_stop, toolbox_computer_use_restart_process
```
## Targets
Each action targets a specific resource type. Possible targets include:
```text
api_key, organization, organization_invitation,
organization_role, organization_user, docker_registry,
runner, sandbox, snapshot, user, volume
```
## Outcomes
The outcome field indicates the result of the action. Statuses follow standard HTTP semantics:
| Outcome | Description |
|---------|-------------|
| **Info** | Informational (1xx codes) |
| **Success** | Action succeeded (2xx codes) |
| **Redirect** | Redirects (3xx codes) |
| **Error** | Client/server error (4xx/5xx) |
Example errors may include:
- `400` – Sandbox is not started
- `403` – Unauthorized
- `500` – Internal error
{/* ## Filtering & Pagination
You can filter and search logs by:
- Action type
- Target resource
- Outcome status
- User email
Use the page size selector to change how many results are shown per page. */}
title: Billing
The [Billing](https://app.daytona.io/dashboard/billing) page in the Daytona Dashboard provides an overview of your Organization's billing, wallet, and usage details.
## Wallet Overview
The Wallet section shows the balance of the Organization's wallet and the amount of credits spent this month.
## Automatic Top-Up
Organizations can set automatic top-up rules for their wallets.
- **Threshold** — When the wallet balance drops to this amount, a top-up is triggered.
- **Target** — The wallet balance is topped up to this amount.
Set both **Threshold** and **Target** to `0` to disable automatic top-up.
## Cost Breakdown
The Cost Breakdown chart shows a breakdown of costs per resource. Users can view consumption for CPU, RAM and Disk and toggle between area and bar charts.
title: Computer Use - Linux
description: Programmatic desktop automation and GUI interaction for Linux environments using Daytona.
import { TabItem, Tabs } from '@astrojs/starlight/components'
**Computer Use** enables programmatic control of desktop environments within Daytona sandboxes. It provides mouse, keyboard, screenshot, and display operations for automating GUI interactions and testing desktop applications.
We recommend using this instance type for most tasks.
## Common Use Cases
- **GUI Application Testing** - Automate interactions with desktop applications, click buttons, fill forms, and validate UI behavior
- **Visual Testing & Screenshots** - Capture screenshots of applications, compare UI states, and perform visual regression testing
- **Desktop Automation** - Automate repetitive desktop tasks, file management through GUI, and complex workflows
- **Human-in-the-Loop** - Access the VNC interface directly from the [Daytona Dashboard](https://app.daytona.io/dashboard/sandboxes) to manually control and interact with the desktop environment alongside automated scripts
## SDK References
Choose your preferred SDK to get started with computer use automation:
### TypeScript SDK
Complete API reference for computer use operations in TypeScript.
[View TypeScript SDK →](/docs/en/typescript-sdk/computer-use)
### Python SDK
Complete API reference for computer use operations in Python (sync & async).
[View Python SDK →](/docs/en/python-sdk/sync/computer-use)
## Quick Example
```python
from daytona import Daytona
# Initialize using environment variables (recommended)
daytona = Daytona()
# Or explicitly configure:
# daytona = Daytona(
# api_key=os.getenv('DAYTONA_API_KEY'),
# api_url=os.getenv('DAYTONA_API_URL', 'https://app.daytona.io/api')
# )
# Create sandbox from default snapshot (includes desktop environment)
sandbox = daytona.create()
# Start computer use processes
result = sandbox.computer_use.start()
print("Computer use started:", result.message)
# Take a screenshot
screenshot = sandbox.computer_use.screenshot.take_full_screen()
# Click and type
sandbox.computer_use.mouse.click(100, 200)
sandbox.computer_use.keyboard.type('Hello, Linux!')
sandbox.computer_use.keyboard.hotkey('ctrl+s')
```
```typescript
import { Daytona } from '@daytonaio/sdk';
// Initialize using environment variables (recommended)
const daytona = new Daytona();
// Or explicitly configure:
// const daytona = new Daytona({
// apiKey: process.env.DAYTONA_API_KEY,
// apiUrl: process.env.DAYTONA_API_URL || 'https://app.daytona.io/api'
// });
// Create sandbox from default snapshot (includes desktop environment)
const sandbox = await daytona.create();
// Start computer use processes
await sandbox.computerUse.start();
// Take a screenshot
const screenshot = await sandbox.computerUse.screenshot.takeFullScreen();
// Click and type
await sandbox.computerUse.mouse.click(100, 200);
await sandbox.computerUse.keyboard.type('Hello, Linux!');
await sandbox.computerUse.keyboard.hotkey('ctrl+s');
```
**Environment Variables (.env file):**
```bash
DAYTONA_API_KEY=your-api-key-here
DAYTONA_API_URL=https://app.daytona.io/api
```
## Related Documentation
- [Computer Use - Windows](/docs/en/computer-use-windows)
- [Computer Use - macOS](/docs/en/computer-use-macos)
title: Computer Use - macOS
description: Programmatic desktop automation and GUI interaction for macOS environments using Daytona.
**Computer Use** enables programmatic control of desktop environments within Daytona sandboxes. It provides mouse, keyboard, screenshot, and display operations for automating GUI interactions and testing desktop applications.
We recommend using this instance type if you need to interact with macOS-only applications.
:::caution[Alpha Access Required]
macOS Computer Use is currently in **private alpha**. To request access, please fill out the [macOS Access Request Form](https://docs.google.com/forms/d/e/1FAIpQLSc9xlGZ49OjWNkyzDPC9Ip3InMRR0ZXY3tcoD-PFQj3ck6gzQ/viewform?usp=sharing&ouid=103304973264148733944).
Once submitted, our team will review your request and reach out with setup instructions and availability details.
:::
## Common Use Cases
- **GUI Application Testing** - Automate interactions with native macOS applications, click buttons, fill forms, and validate UI behavior
- **Visual Testing & Screenshots** - Capture screenshots of applications, compare UI states, and perform visual regression testing
- **Desktop Automation** - Automate repetitive macOS desktop tasks, file management through GUI, and complex workflows
## Getting Started
Once you have access to the macOS Computer Use alpha, you'll be able to programmatically control macOS desktop environments within your Daytona sandboxes. The functionality will include mouse operations, keyboard automation, screenshot capture, and display management specifically optimized for macOS environments.
## Related Documentation
- [Computer Use - Linux](/docs/en/computer-use-linux)
- [Computer Use - Windows](/docs/en/computer-use-windows)
title: Computer Use - Windows
description: Programmatic desktop automation and GUI interaction for Windows environments using Daytona.
**Computer Use** enables programmatic control of desktop environments within Daytona sandboxes. It provides mouse, keyboard, screenshot, and display operations for automating GUI interactions and testing desktop applications.
We recommend using this instance type if you need to interact with Windows-only applications.
:::caution[Alpha Access Required]
Windows Computer Use is currently in **private alpha**. To request access, please fill out the [Access Request Form](https://docs.google.com/forms/d/e/1FAIpQLSfoK-77-VpfsMubw8F4f1opCxIL1AyJUgnM0ONYup5hZ0RTvQ/viewform?usp=dialog).
Once submitted, our team will review your request and reach out with setup instructions and availability details.
:::
## Common Use Cases
- **GUI Application Testing** - Automate interactions with Windows desktop applications, click buttons, fill forms, and validate UI behavior
- **Visual Testing & Screenshots** - Capture screenshots of applications, compare UI states, and perform visual regression testing
- **Desktop Automation** - Automate repetitive Windows desktop tasks, file management through GUI, and complex workflows
## Getting Started
Once you have access to the Windows Computer Use alpha, you'll be able to programmatically control Windows desktop environments within your Daytona sandboxes. The functionality will include mouse operations, keyboard automation, screenshot capture, and display management specifically optimized for Windows environments.
## Related Documentation
- [Computer Use - Linux](/docs/en/computer-use-linux)
- [Computer Use - macOS](/docs/en/computer-use-macos)
title: Configuration
import { TabItem, Tabs } from '@astrojs/starlight/components'
## Configuration Methods
Daytona SDK supports multiple ways to configure your environment, in order of precedence:
1. [**Configuration in code**](#configuration-in-code)
2. [**Environment variables**](#environment-variables)
3. [**.env file**](#env-file)
4. [**Default values**](#default-values)
## Configuration in Code
Daytona SDK provides an option to configure settings using the `DaytonaConfig` class in Python and TypeScript. The `DaytonaConfig` class accepts the following parameters:
- `api_key`: Your Daytona [API Key](/docs/api-keys)
- `api_url`: URL of your Daytona API
- `target`: Daytona Target to create the Sandboxes on.
```python
from daytona import DaytonaConfig
config = DaytonaConfig(
api_key="your-api-key",
api_url="your-api-url",
target="us"
)
```
```typescript
import { DaytonaConfig } from '@daytonaio/sdk';
const config: DaytonaConfig = {
apiKey: "your-api-key",
apiUrl: "your-api-url",
target: "us"
};
```
## Environment Variables
Daytona SDK supports environment variables for configuration. The SDK automatically looks for these environment variables:
| Variable | Description | Optional |
| --------------------- | ------------------------------------------ | -------- |
| **`DAYTONA_API_KEY`** | Your Daytona API key. | No |
| **`DAYTONA_API_URL`** | URL of your Daytona API. | Yes |
| **`DAYTONA_TARGET`** | Daytona Target to create the Sandboxes on. | Yes |
Set environment variables in your shell:
```bash
export DAYTONA_API_KEY=your-api-key
export DAYTONA_API_URL=https://your-api-url
export DAYTONA_TARGET=us
```
```bash
$env:DAYTONA_API_KEY="your-api-key"
$env:DAYTONA_API_URL="https://your-api-url"
$env:DAYTONA_TARGET="us"
```
You can also set these environment variables in a `.env` file.
## .env File
Create a `.env` file in your project root directory:
```bash
DAYTONA_API_KEY=your-api-key
DAYTONA_API_URL=https://your-api-url
DAYTONA_TARGET=us
```
The SDK will automatically read these values when initializing.
## Default Values
If no configuration is provided, Daytona SDK will use its built-in defaults:
| Option | Default Value |
|-----------|---------------------------------|
| API URL | https://app.daytona.io/api |
| Target | us |
title: Custom Domain/Authentication
description: Customize the preview proxy with your own domain and logic.
Daytona allows you to deploy your own custom preview proxy to handle preview URLs for sandboxes. This gives you complete control over the preview experience, including custom domains, authentication, error handling, and styling.
**What you can do with a custom preview proxy:**
- **Custom Domain:** Host your proxy under your own domain (e.g., `preview.yourcompany.com`)
- **User Authentication:** Implement custom authentication logic for private previews
- **Smart Sandbox Management:** Automatically start stopped sandboxes before forwarding users
- **Custom Error Pages:** Style error pages to match your brand
- **Preview Warning Control:** Disable Daytona's preview warning
- **CORS Management:** Override Daytona's default CORS settings
## How It Works
When a user visits a preview URL, your custom proxy receives the request and can:
1. **Authenticate the user** using custom logic
2. **Check sandbox status** and start it if needed
3. **Forward the request** to the actual sandbox
4. **Handle responses** with custom styling and error pages
5. **Send custom headers** to control Daytona's behavior
## Daytona Headers
Your proxy can send special headers to control Daytona's behavior:
#### Disable Preview Warning
To disable Daytona's preview warning page, send:
```
X-Daytona-Skip-Preview-Warning: true
```
#### Disable CORS
To override Daytona's default CORS settings, send:
```
X-Daytona-Disable-CORS: true
```
### Disable Last Activity Update
To prevent sandbox last activity updates when previewing, you can set the `X-Daytona-Skip-Last-Activity-Update` header to `true`.
This will stop Daytona from keeping sandboxes, that have [auto-stop enabled](/docs/sandbox-management#auto-stop-interval), started:
```bash
curl -H "X-Daytona-Skip-Last-Activity-Update: true" \
https://3000-sandbox-123456.proxy.daytona.work
```
### Authentication
For private preview links, users should send:
```
X-Daytona-Preview-Token: {sandboxToken}
```
The `sandboxToken` can be fetched through the [Daytona SDK or API](/docs/en/preview-and-authentication).
## Examples
You can find examples of custom preview proxies on our [Github](https://github.com/daytonaio/daytona-proxy-samples):
- [Typescript Example](https://github.com/daytonaio/daytona-proxy-samples/tree/main/typescript)
- [Golang Example](https://github.com/daytonaio/daytona-proxy-samples/tree/main/go)
title: Analyze Data with AI
description: Use Daytona to run AI-generated code for data analysis and visualization.
import { TabItem, Tabs } from '@astrojs/starlight/components'
import { Image } from 'astro:assets'
import chartImage from '../../../assets/docs/images/chart-0.png'
You can use Daytona Sandbox to run AI-generated code to analyze data. Here's how the AI data analysis workflow typically looks:
1. Your user has a dataset in CSV format or other formats.
2. You prompt the LLM to generate code (usually Python) based on the user's data.
3. The sandbox runs the AI-generated code and returns the results.
4. You display the results to the user.
## Build an AI Data Analyst with Daytona
This example shows how to build an AI-powered data analyst that automatically generates insights and visualizations from CSV data using Daytona's secure sandbox environment.
**What we'll build:** A system that analyzes a vehicle valuation dataset, identifies price relation to manufacturing year, and generates professional visualizations - all through natural language prompts to Claude.
### 1. Project Setup
#### 1.1 Install Dependencies
Install the Daytona SDK and Anthropic SDK to your project:
`bash pip install daytona anthropic python-dotenv `
`bash npm install @daytonaio/sdk @anthropic-ai/sdk dotenv `
#### 1.2 Configure Environment
Get your API keys and configure your environment:
1. **Daytona API key:** Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)
2. **Anthropic API key:** Get it from [Anthropic Console](https://console.anthropic.com/)
Create a `.env` file in your project:
```bash
DAYTONA_API_KEY=dtn_***
ANTHROPIC_API_KEY=sk-ant-***
```
### 2. Dataset Preparation
#### 2.1 Download Dataset
We'll be using a publicly available dataset of vehicle valuation. You can download it directly from:
[https://download.daytona.io/dataset.csv](https://download.daytona.io/dataset.csv)
Download the file and save it as `dataset.csv` in your project directory.
#### 2.2 Initialize Sandbox
Now create a Daytona sandbox and upload your dataset:
```python
from dotenv import load_dotenv
from daytona import Daytona
import os
load_dotenv()
# Create sandbox
daytona = Daytona()
sandbox = daytona.create()
# Upload the dataset to the sandbox
sandbox.fs.upload_file("dataset.csv", "/home/daytona/dataset.csv")
```
```typescript
import 'dotenv/config'
import { Daytona } from '@daytonaio/sdk';
// Create sandbox
const daytona = new Daytona();
const sandbox = await daytona.create()
// Upload the dataset to the sandbox
await sandbox.fs.uploadFile('dataset.csv', '/home/daytona/dataset.csv')
```
### 3. Building the AI Data Analyst
Now we'll create the core functionality that connects Claude with Daytona to analyze data and generate visualizations.
#### 3.1 Code Execution Handler
First, let's create a function to handle code execution and chart extraction:
```python
import base64
def run_ai_generated_code(sandbox, ai_generated_code):
execution = sandbox.process.code_run(ai_generated_code)
if execution.exit_code != 0:
print('AI-generated code had an error.')
print(execution.exit_code)
print(execution.result)
return
# Check for charts in execution artifacts
if not execution.artifacts or not execution.artifacts.charts:
print('No charts found in execution artifacts')
return
result_idx = 0
for result in execution.artifacts.charts:
if result.png: # Save the png to a file (png is in base64 format)
with open(f'chart-{result_idx}.png', 'wb') as f:
f.write(base64.b64decode(result.png))
print(f'Chart saved to chart-{result_idx}.png')
result_idx += 1
```
```typescript
import fs from 'fs'
async function runAIGeneratedCode(sandbox, aiGeneratedCode: string) {
const execution = await sandbox.process.codeRun(aiGeneratedCode)
if (execution.exitCode != 0) {
console.error('AI-generated code had an error.')
console.log(execution.exitCode)
console.log(execution.result)
return
}
// Check for charts in execution artifacts
if (!execution.artifacts || !execution.artifacts.charts) {
console.log('No charts found in execution artifacts')
return
}
let resultIdx = 0
for (const result of execution.artifacts.charts) {
if (result.png) {
// Save the png to a file (png is in base64 format)
fs.writeFileSync(`chart-${resultIdx}.png`, result.png, { encoding: 'base64' })
console.log(`Chart saved to chart-${resultIdx}.png`)
resultIdx++
}
}
}
```
#### 3.2 Creating the Analysis Prompt
Next, we'll create the prompt that tells Claude about our dataset and what analysis we want. This prompt includes:
- Dataset schema and column descriptions
- The specific analysis request (vote average trends over time)
- Instructions for code generation
```python
from anthropic import Anthropic
prompt = f"""
I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.
Relevant columns:
- 'year': integer, the manufacturing year of the vehicle
- 'price_in_euro': float, the listed price of the vehicle in Euros
Analyze how price varies by manufacturing year.
Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.
Create a line chart showing average price per year.
Write Python code that analyzes the dataset based on my request and produces right chart accordingly.
Finish with a plt.show()"""
anthropic = Anthropic()
print('Waiting for the model response...')
```
```typescript
import Anthropic from '@anthropic-ai/sdk'
const prompt = `
I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.
Relevant columns:
- 'year': integer, the manufacturing year of the vehicle
- 'price_in_euro': float, the listed price of the vehicle in Euros
Analyze how price varies by manufacturing year.
Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.
Create a line chart showing average price per year.
Write Python code that analyzes the dataset based on my request and produces right chart accordingly.
Finish with a plt.show()`
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
console.log('Waiting for the model response...')
```
#### 3.3 Tool Calling Setup
Now we'll connect Claude to our Daytona sandbox using tool calling. This allows Claude to automatically execute the Python code it generates:
```python
msg = anthropic.messages.create(
model='claude-3-5-sonnet-20240620',
max_tokens=1024,
messages=[{'role': 'user', 'content': prompt}],
tools=[
{
'name': 'run_python_code',
'description': 'Run Python code',
'input_schema': {
'type': 'object',
'properties': {
'code': {
'type': 'string',
'description': 'The Python code to run',
},
},
'required': ['code'],
},
},
],
)
```
```typescript
const msg = await anthropic.messages.create({
model: 'claude-3-5-sonnet-20240620',
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }],
tools: [
{
name: 'run_python_code',
description: 'Run Python code',
input_schema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'The Python code to run',
},
},
required: ['code'],
},
},
],
})
```
#### 3.4 Response Processing
Finally, we'll parse Claude's response and execute any generated code in our Daytona sandbox:
```python
for content_block in msg.content:
if content_block.type == 'tool_use':
if content_block.name == 'run_python_code':
code = content_block.input['code']
print('Will run following code in the Sandbox:\n', code)
# Execute the code in the sandbox
run_ai_generated_code(sandbox, code)
```
```typescript
interface CodeRunToolInput {
code: string
}
for (const contentBlock of msg.content) {
if (contentBlock.type === 'tool_use') {
if (contentBlock.name === 'run_python_code') {
const code = (contentBlock.input as CodeRunToolInput).code
console.log('Will run following code in the Sandbox:\n', code)
// Execute the code in the sandbox
await runAIGeneratedCode(sandbox, code)
}
}
}
```
That's it! The `run_ai_generated_code` function we created automatically handles saving charts. When Claude generates a visualization with `plt.show()`, Daytona captures it as a chart artifact and saves it as a PNG file.
**Key advantages of this approach:**
- **Secure execution:** Code runs in isolated Daytona sandboxes
- **Automatic artifact capture:** Charts, tables, and outputs are automatically extracted
- **Error handling:** Built-in error detection and logging
- **Language agnostic:** While we used Python here, Daytona supports multiple languages
### 4. Running Your Analysis
Now you can run the complete code to see the results.
```bash
python data-analysis.py
```
```bash
npx tsx data-analysis.ts
```
You should see the chart in your project directory that will look similar to this:
### 5. Complete Implementation
Here are the complete, ready-to-run examples:
```python
import base64
from dotenv import load_dotenv
from daytona import Daytona, Sandbox
from anthropic import Anthropic
def main():
load_dotenv()
# Create sandbox
daytona = Daytona()
sandbox = daytona.create()
# Upload the dataset to the sandbox
sandbox.fs.upload_file("dataset.csv", "/home/daytona/dataset.csv")
prompt = f"""
I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.
Relevant columns:
- 'year': integer, the manufacturing year of the vehicle
- 'price_in_euro': float, the listed price of the vehicle in Euros
Analyze how price varies by manufacturing year.
Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.
Create a line chart showing average price per year.
Write Python code that analyzes the dataset based on my request and produces right chart accordingly.
Finish with a plt.show()"""
anthropic = Anthropic()
print('Waiting for the model response...')
msg = anthropic.messages.create(
model='claude-3-5-sonnet-20240620',
max_tokens=1024,
messages=[{'role': 'user', 'content': prompt}],
tools=[
{
'name': 'run_python_code',
'description': 'Run Python code',
'input_schema': {
'type': 'object',
'properties': {
'code': {
'type': 'string',
'description': 'The Python code to run',
},
},
'required': ['code'],
},
},
],
)
for content_block in msg.content:
if content_block.type == 'tool_use':
if content_block.name == 'run_python_code':
code = content_block.input['code']
print('Will run following code in the Sandbox:\n', code)
# Execute the code in the sandbox
run_ai_generated_code(sandbox, code)
def run_ai_generated_code(sandbox: Sandbox, ai_generated_code: str):
execution = sandbox.process.code_run(ai_generated_code)
if execution.exit_code != 0:
print('AI-generated code had an error.')
print(execution.exit_code)
print(execution.result)
return
# Iterate over all the results and specifically check for png files that will represent the chart.
if not execution.artifacts or not execution.artifacts.charts:
print('No charts found in execution artifacts')
print(execution.artifacts)
return
result_idx = 0
for result in execution.artifacts.charts:
if result.png:
# Save the png to a file
# The png is in base64 format.
with open(f'chart-{result_idx}.png', 'wb') as f:
f.write(base64.b64decode(result.png))
print(f'Chart saved to chart-{result_idx}.png')
result_idx += 1
if __name__ == "__main__":
main()
```
```typescript
import 'dotenv/config'
import fs from 'fs'
import Anthropic from '@anthropic-ai/sdk'
import { Daytona, Sandbox } from '@daytonaio/sdk';
async function main() {
// Create sandbox
const daytona = new Daytona();
const sandbox = await daytona.create()
// Upload the dataset to the sandbox
await sandbox.fs.uploadFile('dataset.csv', '/home/daytona/dataset.csv')
const prompt = `
I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.
Relevant columns:
- 'year': integer, the manufacturing year of the vehicle
- 'price_in_euro': float, the listed price of the vehicle in Euros
Analyze how price varies by manufacturing year.
Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.
Create a line chart showing average price per year.
Write Python code that analyzes the dataset based on my request and produces right chart accordingly.
Finish with a plt.show()`
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
console.log('Waiting for the model response...')
const msg = await anthropic.messages.create({
model: 'claude-3-5-sonnet-20240620',
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }],
tools: [
{
name: 'run_python_code',
description: 'Run Python code',
input_schema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'The Python code to run',
},
},
required: ['code'],
},
},
],
})
interface CodeRunToolInput {
code: string
}
for (const contentBlock of msg.content) {
if (contentBlock.type === 'tool_use') {
if (contentBlock.name === 'run_python_code') {
const code = (contentBlock.input as CodeRunToolInput).code
console.log('Will run following code in the Sandbox:\n', code)
// Execute the code in the sandbox
await runAIGeneratedCode(sandbox, code)
}
}
}
}
async function runAIGeneratedCode(sandbox: Sandbox, aiGeneratedCode: string) {
const execution = await sandbox.process.codeRun(aiGeneratedCode)
if (execution.exitCode != 0) {
console.error('AI-generated code had an error.')
console.log(execution.exitCode)
console.log(execution.result)
process.exit(1)
}
// Iterate over all the results and specifically check for png files that will represent the chart.
if (!execution.artifacts || !execution.artifacts.charts) {
console.log('No charts found in execution artifacts')
console.log(execution.artifacts)
return
}
let resultIdx = 0
for (const result of execution.artifacts.charts) {
if (result.png) {
// Save the png to a file
// The png is in base64 format.
fs.writeFileSync(`chart-${resultIdx}.png`, result.png, { encoding: 'base64' })
console.log(`Chart saved to chart-${resultIdx}.png`)
resultIdx++
}
}
}
main().catch(console.error);
```
title: Declarative Builder
import { TabItem, Tabs } from '@astrojs/starlight/components'
Daytona's declarative builder provides a powerful, code-first approach to defining dependencies for Sandboxes. Instead of importing images from a container registry, you can programmatically define them using the SDK.
## Overview
The declarative builder system supports two primary workflows:
1. [**Declarative Images**](#declarative-image-building): Build images with varying dependencies _on demand_ when creating Sandboxes
2. [**Pre-built Snapshots**](#creating-pre-built-snapshots): Create and register _ready-to-use_ [Snapshots](/docs/snapshots) that can be shared across multiple Sandboxes
### Declarative Image Building
You can create declarative images on-the-fly when creating Sandboxes. This is ideal for iterating quickly without creating separate Snapshots.
Declarative images are cached for 24 hours, and will be automatically reused when running the same script. Thus, subsequent runs on the same Runner will be almost instantaneous.
```python
# Define a simple declarative image with Python packages
declarative_image = (
Image.debian_slim("3.12")
.pip_install(["requests", "pytest"])
.workdir("/home/daytona")
)
# Create a new Sandbox with the declarative image and stream the build logs
sandbox = daytona.create(
CreateSandboxFromImageParams(image=declarative_image),
timeout=0,
on_snapshot_create_logs=print,
)
```
```typescript
// Define a simple declarative image with Python packages
const declarativeImage = Image.debianSlim('3.12')
.pipInstall(['requests', 'pytest'])
.workdir('/home/daytona')
// Create a new Sandbox with the declarative image and stream the build logs
const sandbox = await daytona.create(
{
image: declarativeImage,
},
{
timeout: 0,
onSnapshotCreateLogs: console.log,
}
)
```
See: [CreateSandboxFromImageParams (Python SDK)](/docs/python-sdk/sync/daytona#createsandboxfromimageparams), [CreateSandboxFromImageParams (TypeScript SDK)](/docs/typescript-sdk/daytona#createsandboxfromimageparams)
### Creating Pre-built Snapshots
For images that will be reused across multiple Sandboxes, create a pre-built Snapshot. This Snapshot will remain visible in the Daytona dashboard and be permanently cached, ensuring instant availability without rebuilding.
```python
# Create a simple Python data science image
snapshot_name = "data-science-snapshot"
image = (
Image.debian_slim("3.12")
.pip_install(["pandas", "numpy"])
.workdir("/home/daytona")
)
# Create the Snapshot and stream the build logs
daytona.snapshot.create(
CreateSnapshotParams(
name=snapshot_name,
image=image,
),
on_logs=print,
)
# Create a new Sandbox using the pre-built Snapshot
sandbox = daytona.create(
CreateSandboxFromSnapshotParams(snapshot=snapshot_name)
)
```
```typescript
// Create a simple Python data science image
const snapshotName = 'data-science-snapshot'
const image = Image.debianSlim('3.12')
.pipInstall(['pandas', 'numpy'])
.workdir('/home/daytona')
// Create the Snapshot and stream the build logs
await daytona.snapshot.create(
{
name: snapshotName,
image,
},
{
onLogs: console.log,
}
)
// Create a new Sandbox using the pre-built Snapshot
const sandbox = await daytona.create({
snapshot: snapshotName,
})
```
See: [CreateSnapshotParams (Python SDK)](/docs/python-sdk/sync/snapshot#createsnapshotparams), [CreateSnapshotParams (TypeScript SDK)](/docs/typescript-sdk/snapshot#createsnapshotparams)
## Image Configuration
The Daytona SDK provides methods to define images programmatically using the Daytona SDK. You can specify base images, install packages, add files, set environment variables, and more.
For a complete API reference and method signatures, check the [Python](/docs/python-sdk/common/image) and [TypeScript](/docs/typescript-sdk/image) SDK references.
### Base Image Selection
These examples demonstrate how to select and configure base images:
```python
# Create an image from a base
image = Image.base("python:3.12-slim-bookworm")
# Use a Debian slim image with Python 3.12
image = Image.debian_slim("3.12")
```
```typescript
// Create an image from a base
const image = Image.base('python:3.12-slim-bookworm')
// Use a Debian slim image with Python 3.12
const image = Image.debianSlim('3.12')
```
See: [base (Python SDK)](/docs/python-sdk/common/image#imagebase), [debian_slim (Python SDK)](/docs/python-sdk/common/image#imagedebian_slim), [base (TypeScript SDK)](/docs/typescript-sdk/image#base), [debianSlim (TypeScript SDK)](/docs/typescript-sdk/image#debianslim)
### Package Management
Use these methods to install Python packages and dependencies:
```python
# Add pip packages
image = Image.debian_slim("3.12").pip_install("requests", "pandas")
# Install from requirements.txt
image = Image.debian_slim("3.12").pip_install_from_requirements("requirements.txt")
# Install from pyproject.toml (with optional dependencies)
image = Image.debian_slim("3.12").pip_install_from_pyproject("pyproject.toml", optional_dependencies=["dev"])
```
```typescript
// Add pip packages
const image = Image.debianSlim('3.12').pipInstall(['requests', 'pandas'])
// Install from requirements.txt
const image = Image.debianSlim('3.12').pipInstallFromRequirements('requirements.txt')
// Install from pyproject.toml (with optional dependencies)
const image = Image.debianSlim('3.12').pipInstallFromPyproject('pyproject.toml', {
optionalDependencies: ['dev']
})
```
See: [pip_install (Python SDK)](/docs/python-sdk/common/image#imagepip_install), [pip_install_from_requirements (Python SDK)](/docs/python-sdk/common/image#imagepip_install_from_requirements), [pip_install_from_pyproject (Python SDK)](/docs/python-sdk/common/image#imagepip_install_from_pyproject), [pipInstall (TypeScript SDK)](/docs/typescript-sdk/image#pipinstall), [pipInstallFromRequirements (TypeScript SDK)](/docs/typescript-sdk/image#pipinstallfromrequirements), [pipInstallFromPyproject (TypeScript SDK)](/docs/typescript-sdk/image#pipinstallfrompyproject)
### File System Operations
These examples show how to add files and directories to your image:
```python
# Add a local file
image = Image.debian_slim("3.12").add_local_file("package.json", "/home/daytona/package.json")
# Add a local directory
image = Image.debian_slim("3.12").add_local_dir("src", "/home/daytona/src")
```
```typescript
// Add a local file
const image = Image.debianSlim('3.12').addLocalFile('package.json', '/home/daytona/package.json')
// Add a local directory
const image = Image.debianSlim('3.12').addLocalDir('src', '/home/daytona/src')
```
See: [add_local_file (Python SDK)](/docs/python-sdk/common/image#imageadd_local_file), [add_local_dir (Python SDK)](/docs/python-sdk/common/image#imageadd_local_dir), [addLocalFile (TypeScript SDK)](/docs/typescript-sdk/image#addlocalfile), [addLocalDir (TypeScript SDK)](/docs/typescript-sdk/image#addlocaldir)
### Environment Configuration
Configure environment variables and working directories with these methods:
```python
# Set environment variables
image = Image.debian_slim("3.12").env({"PROJECT_ROOT": "/home/daytona"})
# Set working directory
image = Image.debian_slim("3.12").workdir("/home/daytona")
```
```typescript
// Set environment variables
const image = Image.debianSlim('3.12').env({ PROJECT_ROOT: '/home/daytona' })
// Set working directory
const image = Image.debianSlim('3.12').workdir('/home/daytona')
```
See: [env (Python SDK)](/docs/python-sdk/common/image#imageenv), [workdir (Python SDK)](/docs/python-sdk/common/image#imageworkdir), [env (TypeScript SDK)](/docs/typescript-sdk/image#env), [workdir (TypeScript SDK)](/docs/typescript-sdk/image#workdir)
### Commands and Entrypoints
Execute commands during build and configure container startup behavior:
```python
# Run shell commands during build
image = Image.debian_slim("3.12").run_commands(
'apt-get update && apt-get install -y git',
'groupadd -r daytona && useradd -r -g daytona -m daytona',
'mkdir -p /home/daytona/workspace'
)
# Set entrypoint
image = Image.debian_slim("3.12").entrypoint(["/bin/bash"])
# Set default command
image = Image.debian_slim("3.12").cmd(["/bin/bash"])
```
```typescript
// Run shell commands during build
const image = Image.debianSlim('3.12').runCommands(
'apt-get update && apt-get install -y git',
'groupadd -r daytona && useradd -r -g daytona -m daytona',
'mkdir -p /home/daytona/workspace'
)
// Set entrypoint
const image = Image.debianSlim('3.12').entrypoint(['/bin/bash'])
// Set default command
const image = Image.debianSlim('3.12').cmd(['/bin/bash'])
```
See: [run_commands (Python SDK)](/docs/python-sdk/common/image#imagerun_commands), [entrypoint (Python SDK)](/docs/python-sdk/common/image#imageentrypoint), [cmd (Python SDK)](/docs/python-sdk/common/image#imagecmd), [runCommands (TypeScript SDK)](/docs/typescript-sdk/image#runcommands), [entrypoint (TypeScript SDK)](/docs/typescript-sdk/image#entrypoint), [cmd (TypeScript SDK)](/docs/typescript-sdk/image#cmd)
### Dockerfile Integration
Integrate existing Dockerfiles or add custom Dockerfile commands:
```python
# Add custom Dockerfile commands
image = Image.debian_slim("3.12").dockerfile_commands(["RUN echo 'Hello, world!'"])
# Use an existing Dockerfile
image = Image.from_dockerfile("Dockerfile")
# Extend an existing Dockerfile
image = Image.from_dockerfile("app/Dockerfile").pip_install(["numpy"])
```
```typescript
// Add custom Dockerfile commands
const image = Image.debianSlim('3.12').dockerfileCommands(['RUN echo "Hello, world!"'])
// Use an existing Dockerfile
const image = Image.fromDockerfile('Dockerfile')
// Extend an existing Dockerfile
const image = Image.fromDockerfile("app/Dockerfile").pipInstall(['numpy'])
```
See: [dockerfile_commands (Python SDK)](/docs/python-sdk/common/image#imagedockerfile_commands), [from_dockerfile (Python SDK)](/docs/python-sdk/common/image#imagefrom_dockerfile), [dockerfileCommands (TypeScript SDK)](/docs/typescript-sdk/image#dockerfilecommands), [fromDockerfile (TypeScript SDK)](/docs/typescript-sdk/image#fromdockerfile)
## Best Practices
Use the following best practices when working with the declarative builder:
1. **Layer Optimization**: Group related operations to minimize Docker layers
2. **Cache Utilization**: Identical build commands and context will be cached and subsequent builds will be almost instant
3. **Security**: Create non-root users for application workloads
4. **Resource Efficiency**: Use slim base images when appropriate
5. **Context Minimization**: Only include necessary files in the build context
title: File System Operations
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona SDK provides comprehensive file system operations through the `fs` module in Sandboxes. This guide covers all available file system operations and best practices.
## Basic Operations
Daytona SDK provides an option to interact with the file system in Sandboxes. You can perform various operations like listing files, creating directories, reading and writing files, and more.
File operations assume you are operating in the Sandbox user's home directory (e.g. `workspace` implies `/home/[username]/workspace`). Use a leading `/` when providing absolute paths.
### Listing Files and Directories
Daytona SDK provides an option to list files and directories in a Sandbox using Python and TypeScript.
```python
# List files in a directory
files = sandbox.fs.list_files("workspace")
for file in files:
print(f"Name: {file.name}")
print(f"Is directory: {file.is_dir}")
print(f"Size: {file.size}")
print(f"Modified: {file.mod_time}")
```
```typescript
// List files in a directory
const files = await sandbox.fs.listFiles("workspace")
files.forEach(file => {
console.log(`Name: ${file.name}`)
console.log(`Is directory: ${file.isDir}`)
console.log(`Size: ${file.size}`)
console.log(`Modified: ${file.modTime}`)
})
```
See: [list_files (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemlist_files), [listFiles (TypeScript SDK)](/docs/typescript-sdk/file-system/#listfiles)
### Creating Directories
Daytona SDK provides an option to create directories with specific permissions using Python and TypeScript.
```python
# Create with specific permissions
sandbox.fs.create_folder("workspace/new-dir", "755")
```
```typescript
// Create with specific permissions
await sandbox.fs.createFolder("workspace/new-dir", "755")
```
See: [create_folder (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemcreate_folder), [createFolder (TypeScript SDK)](/docs/typescript-sdk/file-system/#createfolder)
### Uploading Files
Daytona SDK provides options to read, write, upload, download, and delete files in Sandboxes using Python and TypeScript.
#### Uploading a Single File
The following example shows how to upload a single file:
```python
# Upload a single file
with open("local_file.txt", "rb") as f:
content = f.read()
sandbox.fs.upload_file(content, "remote_file.txt")
```
```typescript
// Upload a single file
const fileContent = Buffer.from('Hello, World!')
await sandbox.fs.uploadFile(fileContent, "data.txt")
```
See: [upload_file (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemupload_file), [uploadFile (TypeScript SDK)](/docs/typescript-sdk/file-system/#uploadfile)
#### Uploading Multiple Files
The following example shows how to efficiently upload multiple files with a single method call.
```python
# Upload multiple files at once
files_to_upload = []
with open("file1.txt", "rb") as f1:
files_to_upload.append(FileUpload(
source=f1.read(),
destination="data/file1.txt",
))
with open("file2.txt", "rb") as f2:
files_to_upload.append(FileUpload(
source=f2.read(),
destination="data/file2.txt",
))
with open("settings.json", "rb") as f3:
files_to_upload.append(FileUpload(
source=f3.read(),
destination="config/settings.json",
))
sandbox.fs.upload_files(files_to_upload)
```
```typescript
// Upload multiple files at once
const files = [
{
source: Buffer.from('Content of file 1'),
destination: 'data/file1.txt',
},
{
source: Buffer.from('Content of file 2'),
destination: 'data/file2.txt',
},
{
source: Buffer.from('{"key": "value"}'),
destination: 'config/settings.json',
}
]
await sandbox.fs.uploadFiles(files)
```
See: [upload_files (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemupload_files), [uploadFiles (TypeScript SDK)](/docs/typescript-sdk/file-system/#uploadfiles)
### Downloading Files
#### Downloading a Single File
The following commands downloads a single file `file1.txt` from the Sandbox working directory and prints out the content:
```python
content = sandbox.fs.download_file("file1.txt")
with open("local_file.txt", "wb") as f:
f.write(content)
print(content.decode('utf-8'))
```
```typescript
const downloadedFile = await sandbox.fs.downloadFile("file1.txt")
console.log('File content:', downloadedFile.toString())
```
See: [download_file (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemdownload_file), [downloadFile (TypeScript SDK)](/docs/typescript-sdk/file-system/#downloadfile)
#### Downloading Multiple Files
The following example shows how to efficiently download multiple files with a single method call.
```python
# Download multiple files at once
files_to_download = [
FileDownloadRequest(source="data/file1.txt"), # No destination - download to memory
FileDownloadRequest(source="data/file2.txt", destination="local_file2.txt"), # Download to local file
]
results = sandbox.fs.download_files(files_to_download)
for result in results:
if result.error:
print(f"Error downloading {result.source}: {result.error}")
elif result.result:
print(f"Downloaded {result.source} to {result.result}")
```
```typescript
// Download multiple files at once
const files = [
{ source: "data/file1.txt" }, // No destination - download to memory
{ source: "data/file2.txt", destination: "local_file2.txt" }, // Download to local file
]
const results = await sandbox.fs.downloadFiles(files)
results.forEach(result => {
if (result.error) {
console.error(`Error downloading ${result.source}: ${result.error}`)
} else if (result.result) {
console.log(`Downloaded ${result.source} to ${result.result}`)
}
})
```
See: [download_files (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemdownload_files), [downloadFiles (TypeScript SDK)](/docs/typescript-sdk/file-system/#downloadfiles)
### Deleting files
The following example shows how to delete a file:
```python
sandbox.fs.delete_file("workspace/file.txt")
```
```typescript
await sandbox.fs.deleteFile("workspace/file.txt")
```
See: [delete_file (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemdelete_file), [deleteFile (TypeScript SDK)](/docs/typescript-sdk/file-system/#deletefile)
## Advanced Operations
Daytona SDK provides advanced file system operations like file permissions, search and replace, and more.
### File Permissions
Daytona SDK provides an option to set file permissions, get file permissions, and set directory permissions recursively using Python and TypeScript.
```python
# Set file permissions
sandbox.fs.set_file_permissions("workspace/file.txt", "644")
# Get file permissions
file_info = sandbox.fs.get_file_info("workspace/file.txt")
print(f"Permissions: {file_info.permissions}")
```
```typescript
// Set file permissions
await sandbox.fs.setFilePermissions("workspace/file.txt", { mode: "644" })
// Get file permissions
const fileInfo = await sandbox.fs.getFileDetails("workspace/file.txt")
console.log(`Permissions: ${fileInfo.permissions}`)
```
See: [set_file_permissions (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemset_file_permissions), [setFilePermissions (TypeScript SDK)](/docs/typescript-sdk/file-system/#setfilepermissions)
### File Search and Replace
Daytona SDK provides an option to search for text in files and replace text in files using Python and TypeScript.
```python
# Search for text in files; if a folder is specified, the search is recursive
results = sandbox.fs.find_files(
path="workspace/src",
pattern="text-of-interest"
)
for match in results:
print(f"Absolute file path: {match.file}")
print(f"Line number: {match.line}")
print(f"Line content: {match.content}")
print("\n")
# Replace text in files
sandbox.fs.replace_in_files(
files=["workspace/file1.txt", "workspace/file2.txt"],
pattern="old_text",
new_value="new_text"
)
```
```typescript
// Search for text in files; if a folder is specified, the search is recursive
const results = await sandbox.fs.findFiles({
path="workspace/src",
pattern: "text-of-interest"
})
results.forEach(match => {
console.log('Absolute file path:', match.file)
console.log('Line number:', match.line)
console.log('Line content:', match.content)
})
// Replace text in files
await sandbox.fs.replaceInFiles(
["workspace/file1.txt", "workspace/file2.txt"],
"old_text",
"new_text"
)
```
See: [find_files (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemfind_files), [replace_in_files (Python SDK)](/docs/python-sdk/sync/file-system/#filesystemreplace_in_files), [findFiles (TypeScript SDK)](/docs/typescript-sdk/file-system/#findfiles), [replaceInFiles (TypeScript SDK)](/docs/typescript-sdk/file-system/#replaceinfiles)
title: Getting Started
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona SDK provides official [Python](/docs/en/python-sdk) and [TypeScript](/docs/en/typescript-sdk) interfaces for interacting with Daytona, enabling you to programmatically manage development environments and execute code. [Python SDK](/docs/en/python-sdk) supports both sync and async programming models where async classes are prefixed with `Async`.
Follow the step-by-step guide to create and run your first Daytona Sandbox for an AI Agent.
For steps on additional configuration, including setting environment variables as well as accessing experimental features on our staging deployment, visit [Configuration](/docs/en/configuration).
## Install the Daytona SDK
Daytona provides official Python and TypeScript SDKs for interacting with the Daytona platform. Install the SDK using your preferred method:
```bash
pip install daytona
```
```bash
# Using npm
npm install @daytonaio/sdk
# Using yarn
yarn add @daytonaio/sdk
# Using pnpm
pnpm add @daytonaio/sdk
```
## Run Code Inside a Sandbox
Run the following code to create a Daytona Sandbox and execute commands:
```python
from daytona import Daytona, DaytonaConfig
# Initialize the Daytona client
daytona = Daytona(DaytonaConfig(api_key="YOUR_API_KEY"))
# Create the Sandbox instance
sandbox = daytona.create()
# Run code securely inside the Sandbox
response = sandbox.process.code_run('print("Sum of 3 and 4 is " + str(3 + 4))')
if response.exit_code != 0:
print(f"Error running code: {response.exit_code} {response.result}")
else:
print(response.result)
# Clean up the Sandbox
sandbox.delete()
```
```typescript
import { Daytona } from '@daytonaio/sdk'
async function main() {
// Initialize the Daytona client
const daytona = new Daytona({
apiKey: 'YOUR_API_KEY',
})
let sandbox;
try {
// Create the Sandbox instance
sandbox = await daytona.create({
language: "python",
});
// Run code securely inside the Sandbox
const response = await sandbox.process.codeRun(
'print("Sum of 3 and 4 is " + str(3 + 4))'
);
if (response.exitCode !== 0) {
console.error("Error running code:", response.exitCode, response.result);
} else {
console.log(response.result);
}
} catch (error) {
console.error("Sandbox flow error:", error);
} finally {
// Clean up the Sandbox
if (sandbox) {
await sandbox.delete();
}
}
}
main().catch(console.error)
```
```bash
python main.py
```
```bash
npx tsx ./index.ts
```
## Preview Your App
The following snippet uploads a file containing a simple Flask app to a Daytona Sandbox. The web server runs on port `3000` and is accessible through the provided preview URL:
```python
from daytona import Daytona, DaytonaConfig, SessionExecuteRequest
daytona = Daytona(DaytonaConfig(api_key="YOUR_API_KEY"))
sandbox = daytona.create()
app_code = b'''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return """
Hello World
This web app is running in a Daytona sandbox!
"""
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
'''
# Save the Flask app to a file
sandbox.fs.upload_file(app_code, "app.py")
# Create a new session and execute a command
exec_session_id = "python-app-session"
sandbox.process.create_session(exec_session_id)
sandbox.process.execute_session_command(exec_session_id, SessionExecuteRequest(
command="python /app.py",
var_async=True
))
# Get the preview link for the Flask app
preview_info = sandbox.get_preview_link(3000)
print(f"Flask app is available at: {preview_info.url}")
```
```typescript
import { Daytona } from '@daytonaio/sdk';
const daytona = new Daytona(({
apiKey: "YOUR_API_KEY"
}));
async function main() {
const sandbox = await daytona.create();
const appCode = Buffer.from(`
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return """
Hello World
This web app is running in a Daytona sandbox!
"""
if __name__ == '__main__':
app.run(host='0.0.0.0', port=3000)
`);
// Save the Flask app to a file
await sandbox.fs.uploadFile(appCode, "app.py");
// Create a new session and execute a command
const execSessionId = "python-app-session";
await sandbox.process.createSession(execSessionId);
await sandbox.process.executeSessionCommand(execSessionId, ({
command: `python app.py`,
async: true,
}));
// Get the preview link for the Flask app
const previewInfo = await sandbox.getPreviewLink(3000);
console.log(`Flask app is available at: ${previewInfo.url}`);
}
main().catch(error => console.error("Error:", error));
```
Need to access this endpoint programmatically? Learn more about [Preview & Authentication](/docs/en/preview-and-authentication).
:::tip
You can access the Sandbox [Web Terminal](/docs/en/web-terminal) by printing out the preview URL for port `22222` or by simply going to Dashboard -> Sandboxes and clicking on the Terminal input sign.
:::
## Connect to an LLM
The following snippet connects to an LLM using the Anthropic API and asks Claude to generate code for getting the factorial of 25 and then executes it inside of a Daytona Sandbox:
````python
import os
import re
import requests
from daytona import Daytona, DaytonaConfig
from dotenv import load_dotenv
load_dotenv()
daytona = Daytona(DaytonaConfig())
sandbox = daytona.create()
def get_claude_response(api_key, prompt):
url = "https://api.anthropic.com/v1/messages"
headers = {
"x-api-key": api_key,
"anthropic-version": "2023-06-01",
"Content-Type": "application/json"
}
data = {
"model": "claude-3-7-sonnet-latest",
"max_tokens": 256,
"messages": [{"role": "user", "content": prompt}]
}
response = requests.post(url, json=data, headers=headers)
if response.status_code == 200:
content = response.json().get("content", [])
return "".join([item["text"] for item in content if item["type"] == "text"])
else:
return f"Error {response.status_code}: {response.text}"
prompt = "Python code that returns the factorial of 25. Output only the code. No explanation. No intro. No comments. Just raw code in a single code block."
result = get_claude_response(os.environ["ANTHROPIC_API_KEY"], prompt)
code_match = re.search(r"```python\n(.*?)```", result, re.DOTALL)
code = code_match.group(1) if code_match else result
code = code.replace('\\', '\\\\')
# Run Python code inside the Sandbox and get the output
response = sandbox.process.code_run(code)
print("The factorial of 25 is", response.result)
````
Running the snippet:
```bash
ANTHROPIC_API_KEY="your-anthropic-api-key"
DAYTONA_API_KEY="your-daytona-api-key"
DAYTONA_TARGET=us
python claude-example.py
```
```bash
> The factorial of 25 is 15511210043330985984000000
```
````typescript
import { Daytona } from '@daytonaio/sdk'
import * as dotenv from 'dotenv'
import axios from 'axios'
dotenv.config()
const daytona = new Daytona()
async function getClaudeResponse(apiKey: string, prompt: string): Promise {
const url = "https://api.anthropic.com/v1/messages"
const headers = {
"x-api-key": apiKey,
"anthropic-version": "2023-06-01",
"Content-Type": "application/json"
}
const data = {
"model": "claude-3-7-sonnet-latest",
"max_tokens": 256,
"messages": [{"role": "user", "content": prompt}]
}
try {
const response = await axios.post(url, data, { headers })
if (response.status === 200) {
const content = response.data.content || []
return content
.filter((item: any) => item.type === "text")
.map((item: any) => item.text)
.join("")
} else {
return `Error ${response.status}: ${response.statusText}`
}
} catch (error: any) {
return `Error: ${error.message}`
}
}
async function main() {
const sandbox = await daytona.create()
const prompt = "Python code that returns the factorial of 25. Output only the code. No explanation. No intro. No comments. Just raw code in a single code block."
const result = await getClaudeResponse(process.env.ANTHROPIC_API_KEY || "", prompt)
// Extract code from the response using regex
const codeMatch = result.match(/```python\n(.*?)```/s)
let code = codeMatch ? codeMatch[1] : result
code = code.replace(/\\/g, '\\\\')
// Run the extracted code in the sandbox
const response = await sandbox.process.codeRun(code)
console.log("The factorial of 25 is", response.result)
}
main().catch(console.error)
````
Running the snippet:
```bash
ANTHROPIC_API_KEY="your-anthropic-api-key"
DAYTONA_API_KEY="your-daytona-api-key"
DAYTONA_TARGET=us
npx ts-node claude-example.ts
```
```bash
> The factorial of 25 is 15511210043330985984000000
```
## Additional Examples
Use the Daytona SDK [Python examples](https://github.com/daytonaio/daytona/tree/main/examples/python) or [TypeScript/JavaScript examples](https://github.com/daytonaio/daytona/tree/main/examples/typescript) to create a Sandbox and run your code.
Speed up your development on Daytona using LLMs. Copy the /llms.txt files and include them into your projects or chat context: [llms-full.txt](https://www.daytona.io/docs/llms-full.txt) or [llms.txt](https://www.daytona.io/docs/llms.txt)
Learn more by checking out the Daytona SDK repository on [GitHub](https://github.com/daytonaio/daytona).
## Multiple Runtime Support
The Daytona TypeScript SDK works across multiple JavaScript runtimes including Node.js, Deno, Bun, browsers, and serverless platforms (Cloudflare Workers, AWS Lambda, Azure Functions, etc.).
:::note[Browser and Framework Configuration]
When using the SDK in browser-based environments or frameworks like Vite and Next.js, you'll need to configure node polyfills. See the sections below for setup instructions.
:::
### Daytona in Vite Projects
When using Daytona SDK in a Vite-based project, you need to configure node polyfills to ensure compatibility. Add the following configuration to your `vite.config.ts` file in the plugins array:
```typescript
import { nodePolyfills } from 'vite-plugin-node-polyfills'
plugins: [
// ... other plugins
nodePolyfills({
globals: { global: true, process: true, Buffer: true },
overrides: {
path: 'path-browserify-win32',
},
}),
],
// ... rest of your config
})
```
### Daytona in Next.js Projects
When using Daytona SDK in a Next.js project, you need to configure node polyfills to ensure compatibility with Webpack and Turbopack bundlers (depending on what you're using). Add the following configuration to your `next.config.ts` file:
```typescript
import type { NextConfig } from 'next'
import NodePolyfillPlugin from 'node-polyfill-webpack-plugin'
import { env, nodeless } from 'unenv'
const { alias: turbopackAlias } = env(nodeless, {})
const nextConfig: NextConfig = {
// Turbopack
experimental: {
turbo: {
resolveAlias: {
...turbopackAlias,
},
},
},
// Webpack
webpack: (config, { isServer }) => {
if (!isServer) {
config.plugins.push(new NodePolyfillPlugin())
}
return config
},
}
```
## Setting up the Daytona CLI
If you want to use [images from your local device](/docs/en/snapshots#using-a-local-image) or simply prefer managing your Sandboxes using the command line interface, install the Daytona CLI by running:
```bash
brew install daytonaio/cli/daytona
```
```bash
powershell -Command "irm https://get.daytona.io/windows | iex"
```
title: Git Operations
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona SDK provides built-in Git support through the `git` module in Sandboxes. This guide covers all available Git operations and best practices.
## Basic Operations
Daytona SDK provides an option to clone, check status, and manage Git repositories in Sandboxes. You can interact with Git repositories using the `git` module.
Similarly to file operations the starting cloning dir is the current Sandbox working directory. Uses the WORKDIR specified in
the Dockerfile if present, or falling back to the user's home directory if not - e.g. `workspace/repo` implies `/my-work-dir/workspace/repo`, but you are free to provide an absolute workDir path as well (by starting the path with `/`).
### Cloning Repositories
Daytona SDK provides an option to clone Git repositories into Sandboxes using Python and TypeScript. You can clone public or private repositories, specific branches, and authenticate using personal access tokens.
```python
# Basic clone
sandbox.git.clone(
url="https://github.com/user/repo.git",
path="workspace/repo"
)
# Clone with authentication
sandbox.git.clone(
url="https://github.com/user/repo.git",
path="workspace/repo",
username="git",
password="personal_access_token"
)
# Clone specific branch
sandbox.git.clone(
url="https://github.com/user/repo.git",
path="workspace/repo",
branch="develop"
)
```
```typescript
// Basic clone
await sandbox.git.clone(
"https://github.com/user/repo.git",
"workspace/repo"
);
// Clone with authentication
await sandbox.git.clone(
"https://github.com/user/repo.git",
"workspace/repo",
undefined,
undefined,
"git",
"personal_access_token"
);
// Clone specific branch
await sandbox.git.clone(
"https://github.com/user/repo.git",
"workspace/repo",
"develop"
);
```
See: [clone (Python SDK)](/docs/python-sdk/sync/git/#gitclone), [clone (TypeScript SDK)](/docs/typescript-sdk/git/#clone)
### Repository Status
Daytona SDK provides an option to check the status of Git repositories in Sandboxes. You can get the current branch, modified files, number of commits ahead and behind main branch using Python and TypeScript.
```python
# Get repository status
status = sandbox.git.status("workspace/repo")
print(f"Current branch: {status.current_branch}")
print(f"Commits ahead: {status.ahead}")
print(f"Commits behind: {status.behind}")
for file in status.file_status:
print(f"File: {file.name}")
# List branches
response = sandbox.git.branches("workspace/repo")
for branch in response.branches:
print(f"Branch: {branch}")
```
```typescript
// Get repository status
const status = await sandbox.git.status("workspace/repo");
console.log(`Current branch: ${status.currentBranch}`);
console.log(`Commits ahead: ${status.ahead}`);
console.log(`Commits behind: ${status.behind}`);
status.fileStatus.forEach(file => {
console.log(`File: ${file.name}`);
});
// List branches
const response = await sandbox.git.branches("workspace/repo");
response.branches.forEach(branch => {
console.log(`Branch: ${branch}`);
});
```
See: [status (Python SDK)](/docs/python-sdk/sync/git/#gitstatus), [status (TypeScript SDK)](/docs/typescript-sdk/git/#status)
## Branch Operations
Daytona SDK provides an option to manage branches in Git repositories. You can create, switch, and delete branches.
### Managing Branches
Daytona SDK provides an option to create, switch, and delete branches in Git repositories using Python and TypeScript.
```python
# Create new branch
sandbox.git.create_branch("workspace/repo", "feature/new-feature")
# Switch branch
sandbox.git.checkout_branch("workspace/repo", "feature/new-feature")
# Delete branch
sandbox.git.delete_branch("workspace/repo", "feature/old-feature")
```
```typescript
// Create new branch
await sandbox.git.createBranch("workspace/repo", "feature/new-feature");
// Switch branch
await sandbox.git.checkoutBranch("workspace/repo", "feature/new-feature");
// Delete branch
await sandbox.git.deleteBranch("workspace/repo", "feature/old-feature");
```
See: [create_branch (Python SDK)](/docs/python-sdk/sync/git/#gitcreate_branch), [checkout_branch (Python SDK)](/docs/python-sdk/sync/git/#gitcheckout_branch), [delete_branch (Python SDK)](/docs/python-sdk/sync/git/#gitdelete_branch), [createBranch (TypeScript SDK)](/docs/typescript-sdk/git/#createbranch), [checkoutBranch (TypeScript SDK)](/docs/typescript-sdk/git/#checkoutbranch), [deleteBranch (TypeScript SDK)](/docs/typescript-sdk/git/#deletebranch)
## Staging and Committing
Daytona SDK provides an option to stage and commit changes in Git repositories. You can stage specific files, all changes, and commit with a message using Python and TypeScript.
### Working with Changes
```python
# Stage specific files
sandbox.git.add("workspace/repo", ["file1.txt", "file2.txt"])
# Stage all changes
sandbox.git.add("workspace/repo", ["."])
# Commit changes
sandbox.git.commit("workspace/repo", "feat: add new feature", "John Doe", "john@example.com")
```
```typescript
// Stage specific files
await sandbox.git.add("workspace/repo", ["file1.txt", "file2.txt"]);
// Stage all changes
await sandbox.git.add("workspace/repo", ["."]);
// Commit changes
await sandbox.git.commit("workspace/repo", "feat: add new feature", "John Doe", "john@example.com");
```
See: [add (Python SDK)](/docs/python-sdk/sync/git/#gitadd), [commit (Python SDK)](/docs/python-sdk/sync/git/#gitcommit), [add (TypeScript SDK)](/docs/typescript-sdk/git/#add), [commit (TypeScript SDK)](/docs/typescript-sdk/git/#commit)
## Remote Operations
Daytona SDK provides an option to work with remote repositories in Git.
### Working with Remotes
Daytona SDK provides an option to push and pull changes using Python and TypeScript.
```python
# Push changes
sandbox.git.push("workspace/repo")
# Pull changes
sandbox.git.pull("workspace/repo")
```
```typescript
// Push changes
await sandbox.git.push("workspace/repo");
// Pull changes
await sandbox.git.pull("workspace/repo");
```
See: [push (Python SDK)](/docs/python-sdk/sync/git/#gitpush), [pull (Python SDK)](/docs/python-sdk/sync/git/#gitpull), [push (TypeScript SDK)](/docs/typescript-sdk/git/#push), [pull (TypeScript SDK)](/docs/typescript-sdk/git/#pull)
title: Daytona Documentation
description: Start managing your Sandboxes with Daytona.
template: doc
head:
- tag: title
content: Documentation · Daytona
- tag: meta
attrs:
property: og:title
content: Documentation · Daytona
- tag: meta
attrs:
name: twitter:title
content: Documentation · Daytona
tableOfContents: false
import { Tabs, TabItem } from '@astrojs/starlight/components';
The Daytona SDK provides official Python and TypeScript interfaces for interacting with Daytona,
enabling you to programmatically manage development environments and execute code.
### Quick Start
Run your first line of code in a Daytona Sandbox. Use our [LLMs context files](/docs/en/getting-started#additional-examples) for faster development with AI assistants.
#### 1. Get Your API Key
- Go to the Daytona [Dashboard](https://app.daytona.io/dashboard).
- Create a new [API key](https://app.daytona.io/dashboard/keys). Make sure to save it securely,
as it won't be shown again.
#### 2. Install the SDK
```bash
pip install daytona
```
```bash
npm install @daytonaio/sdk
```
#### 3. Write Your Code
Create a file named: `main.py`
```python
from daytona import Daytona, DaytonaConfig
# Define the configuration
config = DaytonaConfig(api_key="your-api-key")
# Initialize the Daytona client
daytona = Daytona(config)
# Create the Sandbox instance
sandbox = daytona.create()
# Run the code securely inside the Sandbox
response = sandbox.process.code_run('print("Hello World from code!")')
if response.exit_code != 0:
print(f"Error: {response.exit_code} {response.result}")
else:
print(response.result)
# Clean up
sandbox.delete()
```
Create a file named: `index.mts`
```typescript
import { Daytona } from '@daytonaio/sdk';
// Initialize the Daytona client
const daytona = new Daytona({ apiKey: 'your-api-key' });
// Create the Sandbox instance
const sandbox = await daytona.create({
language: 'typescript',
});
// Run the code securely inside the Sandbox
const response = await sandbox.process.codeRun('console.log("Hello World from code!")')
console.log(response.result);
// Clean up
await sandbox.delete()
```
:::note
Replace `your-api-key` with the value from your Daytona dashboard.
:::
#### 4. Run It
```bash
python main.py
```
```bash
npx tsx index.mts
```
#### ✅ What You Just Did
- Installed the Daytona SDK.
- Created a secure sandbox environment.
- Executed code remotely inside that sandbox.
- Retrieved and displayed the output locally.
You're now ready to use Daytona for secure, isolated code execution.
title: Language Server Protocol
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona SDK provides Language Server Protocol (LSP) support through Sandbox instances. This enables advanced language features like code completion, diagnostics, and more.
## Creating LSP Servers
Daytona SDK provides an option to create LSP servers in Python and TypeScript. The `path_to_project` argument is relative to the current Sandbox working directory when no leading `/` is used. The working directory is specified by WORKDIR when it is present in the Dockerfile, and otherwise falls back to the user's home directory.
```python
from daytona import Daytona, LspLanguageId
# Create Sandbox
daytona = Daytona()
sandbox = daytona.create()
# Create LSP server for Python
lsp_server = sandbox.create_lsp_server(
language_id=LspLanguageId.PYTHON,
path_to_project="workspace/project"
)
```
```typescript
import { Daytona, LspLanguageId } from '@daytonaio/sdk'
// Create sandbox
const daytona = new Daytona()
const sandbox = await daytona.create({
language: 'typescript'
})
// Create LSP server for TypeScript
const lspServer = await sandbox.createLspServer(
LspLanguageId.TYPESCRIPT,
"workspace/project"
)
```
See: [create_lsp_server (Python SDK)](/docs/python-sdk/sync/sandbox#sandboxcreate_lsp_server), [createLspServer (TypeScript SDK)](/docs/typescript-sdk/sandbox#createlspserver)
### Supported Languages
The supported languages for creating LSP servers with the Daytona SDK are defined by the `LspLanguageId` enum:
| Enum Value | Description |
|------------------------------|-------------------------------------|
| `LspLanguageId.PYTHON` | Python language server. |
| `LspLanguageId.TYPESCRIPT` | TypeScript/JavaScript language server. |
See: [LspLanguageId (Python SDK)](/docs/python-sdk/sync/lsp-server/#lsplanguageid), [LspLanguageId (TypeScript SDK)](/docs/typescript-sdk/lsp-server/#lsplanguageid)
## LSP Features
Daytona SDK provides LSP features for code analysis and editing.
### Code Completion
Daytona SDK provides an option to get code completions for a specific position in a file using Python and TypeScript.
```python
completions = lsp_server.completions(
path="workspace/project/main.py",
position={"line": 10, "character": 15}
)
print(f"Completions: {completions}")
```
```typescript
const completions = await lspServer.completions(
"workspace/project/main.ts",
{ line: 10, character: 15 }
)
console.log('Completions:', completions)
```
See: [completions (Python SDK)](/docs/python-sdk/sync/lsp-server/#lspservercompletions), [completions (TypeScript SDK)](/docs/typescript-sdk/lsp-server/#completions)
title: Limits
Daytona enforces resource limits to ensure fair usage and stability across all organizations. Your organization has access to a compute pool consisting of:
- **vCPU** — Total CPU cores available
- **Memory** — Total RAM available
- **Storage** — Total disk space available
Resources are shared across all running Sandboxes, so the number of Sandboxes you can run at once depends on their individual usage.
You can see default values and how to configure usage under [Sandbox Resources](/docs/en/sandbox-management/#sandbox-resources). Check your current usage and limits in the [Dashboard](https://app.daytona.io/dashboard/limits).
## Tiers & Limit Increases
Organizations are automatically placed into a Tier based on verification status.\
You can unlock higher limits by completing the following steps:
| Tier | Resources (vCPU / RAM / Storage) | Access Requirements |
| ------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Tier 1 | 10 / 10GiB / 30GiB | Email verified |
| Tier 2 | 100 / 200GiB / 300GiB | Credit card linked, $25 top-up, [GitHub connected](/docs/en/linked-accounts#how-to-link-an-account). |
| Tier 3 | 250 / 500GiB / 2000GiB | Business email verified, Phone verified, $500 top-up. |
| Tier 4 | 500 / 1000GiB / 5000GiB | $2000 top-up every 30 days. |
| Custom | Custom limits | Contact [support@daytona.io](mailto:support@daytona.io) |
Once you meet the criteria for a higher tier, make sure to Upgrade by clicking the "Upgrade" button in the [Dashboard](https://app.daytona.io/dashboard/limits).
## Manage usage dynamically
You can manage your resource usage by [changing the state](http://localhost:4321/docs/sandbox-management#sandbox-lifecycle) of your Sandboxes. The table below summarizes how each state affects resource usage:
| State | vCPU | Memory | Storage | Notes |
|------------|:-------:|:--------:|:------:|------------------------------------------------------------|
| Running | ✅ | ✅ | ✅ | Counts against all limits |
| Stopped | ❌ | ❌ | ✅ | Frees CPU & memory, but storage is still used |
| Archived| ❌ | ❌ | ❌ | Data moved to cold storage, no quota impact |
| Deleted | ❌ | ❌ | ❌ | All resources freed |
See [Sandbox Management](/docs/en/sandbox-management/) for more information.
## Need More?
If you need higher or specialized limits, reach out to [support@daytona.io](mailto:support@daytona.io).
title: Linked Accounts
Daytona supports the linking of user accounts from various identity providers. At the moment, the following providers are supported:
- Google
- GitHub
You can log into your Daytona account using any linked provider.
:::tip
#### Unlock higher usage limits
Linking your GitHub account is one of the requirements to automatically upgrade to Tier 2.
:::
## Linking/Unlinking Accounts
To link or unlink an account:
1. Visit the [Linked Accounts](https://app.daytona.io/dashboard/user/linked-accounts) page in the Daytona dashboard.
2. Use the "Link Account" or "Unlink" button next to the provider you wish to manage.
## Need More?
If you need support for other identity providers, reach out to [support@daytona.io](mailto:support@daytona.io).
title: Log Streaming
When executing long-running processes in a sandbox, you’ll often want to access and process their logs in **real-time**.
The Daytona SDK supports both:
- `Fetching log snapshot` — retrieve all logs up to a certain point.
- `Log streaming` — stream logs as they are being produced, while the process is still running.
This guide covers how to use log streaming in both asynchronous and synchronous modes.
Real-time streaming is especially useful for **debugging**, **monitoring**, or integrating with **observability tools**.
:::note
Starting with version `0.27.0`, you can retrieve session command logs in two distinct streams: **stdout** and **stderr**.
:::
## Streaming Logs with Callbacks
If your sandboxed process is part of a larger system and is expected to run for an extended period (or indefinitely),
you can process logs asynchronously **in the background**, while the rest of your system continues executing.
This is ideal for:
- Continuous monitoring
- Debugging long-running jobs
- Live log forwarding or visualizations
import { TabItem, Tabs } from '@astrojs/starlight/components'
```python
import asyncio
from daytona import Daytona, SessionExecuteRequest
async def main():
daytona = Daytona()
sandbox = daytona.create()
session_id = "streaming-session"
sandbox.process.create_session(session_id)
command = sandbox.process.execute_session_command(
session_id,
SessionExecuteRequest(
command='for i in {1..5}; do echo "Step $i"; echo "Error $i" >&2; sleep 1; done',
var_async=True,
),
)
# Stream logs with separate callbacks
logs_task = asyncio.create_task(
sandbox.process.get_session_command_logs_async(
session_id,
command.cmd_id,
lambda stdout: print(f"[STDOUT]: {stdout}"),
lambda stderr: print(f"[STDERR]: {stderr}"),
)
)
print("Continuing execution while logs are streaming...")
await asyncio.sleep(3)
print("Other operations completed!")
# Wait for the logs to complete
await logs_task
sandbox.delete()
if __name__ == "__main__":
asyncio.run(main())
```
```typescript
import { Daytona, SessionExecuteRequest } from '@daytonaio/sdk'
async function main() {
const daytona = new Daytona()
const sandbox = await daytona.create()
const sessionId = "exec-session-1"
await sandbox.process.createSession(sessionId)
const command = await sandbox.process.executeSessionCommand(
sessionId,
{
command: 'for i in {1..5}; do echo "Step $i"; echo "Error $i" >&2; sleep 1; done',
runAsync: true,
},
)
// Stream logs with separate callbacks
const logsTask = sandbox.process.getSessionCommandLogs(
sessionId,
command.cmdId!,
(stdout) => console.log('[STDOUT]:', stdout),
(stderr) => console.log('[STDERR]:', stderr),
)
console.log('Continuing execution while logs are streaming...')
await new Promise((resolve) => setTimeout(resolve, 3000))
console.log('Other operations completed!')
// Wait for the logs to complete
await logsTask
await sandbox.delete()
}
main()
```
See: [get_session_command_logs_async (Python SDK)](/docs/python-sdk/sync/process/#processget_session_command_logs_async), [getSessionCommandLogs (TypeScript SDK)](/docs/typescript-sdk/process/#getsessioncommandlogs)
## Retrieve All Existing Logs
If the command has a predictable duration, or if you don't need to run it in the background but want to
periodically check all existing logs, you can use the following example to get the logs up to the current point in time.
```python
import time
from daytona import Daytona, SessionExecuteRequest
daytona = Daytona()
sandbox = daytona.create()
session_id = "exec-session-1"
sandbox.process.create_session(session_id)
# Execute a blocking command and wait for the result
command = sandbox.process.execute_session_command(
session_id, SessionExecuteRequest(command="echo 'Hello from stdout' && echo 'Hello from stderr' >&2")
)
print(f"[STDOUT]: {command.stdout}")
print(f"[STDERR]: {command.stderr}")
print(f"[OUTPUT]: {command.output}")
# Or execute command in the background and get the logs later
command = sandbox.process.execute_session_command(
session_id,
SessionExecuteRequest(
command='while true; do if (( RANDOM % 2 )); then echo "All good at $(date)"; else echo "Oops, an error at $(date)" >&2; fi; sleep 1; done',
run_async=True
)
)
time.sleep(5)
# Get the logs up to the current point in time
logs = sandbox.process.get_session_command_logs(session_id, command.cmd_id)
print(f"[STDOUT]: {logs.stdout}")
print(f"[STDERR]: {logs.stderr}")
print(f"[OUTPUT]: {logs.output}")
sandbox.delete()
```
```typescript
import { Daytona, SessionExecuteRequest } from '@daytonaio/sdk'
async function main() {
const daytona = new Daytona()
const sandbox = await daytona.create()
const sessionId = "exec-session-1"
await sandbox.process.createSession(sessionId)
// Execute a blocking command and wait for the result
const command = await sandbox.process.executeSessionCommand(
sessionId,
{
command: 'echo "Hello from stdout" && echo "Hello from stderr" >&2',
},
)
console.log(`[STDOUT]: ${command.stdout}`)
console.log(`[STDERR]: ${command.stderr}`)
console.log(`[OUTPUT]: ${command.output}`)
// Or execute command in the background and get the logs later
const command2 = await sandbox.process.executeSessionCommand(
sessionId,
{
command: 'while true; do if (( RANDOM % 2 )); then echo "All good at $(date)"; else echo "Oops, an error at $(date)" >&2; fi; sleep 1; done',
runAsync: true,
},
)
await new Promise((resolve) => setTimeout(resolve, 5000))
// Get the logs up to the current point in time
const logs = await sandbox.process.getSessionCommandLogs(sessionId, command2.cmdId!)
console.log(`[STDOUT]: ${logs.stdout}`)
console.log(`[STDERR]: ${logs.stderr}`)
console.log(`[OUTPUT]: ${logs.output}`)
await sandbox.delete()
}
main()
```
See: [get_session_command_logs_async (Python SDK)](/docs/python-sdk/sync/process/#processget_session_command_logs_async), [getSessionCommandLogs (TypeScript SDK)](/docs/typescript-sdk/process/#getsessioncommandlogs)
title: Daytona MCP Server
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona Model Context Protocol (MCP) Server enables AI agents to interact with Daytona's features programmatically. This guide covers how to set up and use the MCP server with various AI agents.
## Prerequisites
Before getting started, ensure you have:
- A Daytona account
- Daytona CLI installed
- A compatible AI agent (Claude Desktop App, Claude Code, Cursor, or Windsurf)
## Installation and Setup
### 1. Install Daytona CLI
```bash
brew install daytonaio/cli/daytona
```
```bash
powershell -Command "irm https://get.daytona.io/windows | iex"
```
### 2. Authenticate with Daytona
```bash
daytona login
```
### 3. Initialize MCP Server
Initialize the Daytona MCP server with your preferred AI agent:
```bash
daytona mcp init [claude/cursor/windsurf]
```
### 4. Open Your AI Agent
After initialization, open your AI agent application to begin using Daytona features.
## Integration with Other AI Agents
To integrate Daytona MCP with other AI agents, follow these steps:
1. Generate the MCP configuration:
```bash
daytona mcp config
```
This command outputs a JSON configuration that you can copy into your agent's settings:
```json
{
"mcpServers": {
"daytona-mcp": {
"command": "daytona",
"args": ["mcp", "start"],
"env": {
"HOME": "${HOME}",
"PATH": "${HOME}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin"
},
"logFile": "${HOME}/Library/Logs/daytona/daytona-mcp-server.log"
}
}
}
```
:::note
For Windows users, add the following to the `env` field:
```json
"APPDATA": "${APPDATA}"
```
:::
2. Open or restart your AI agent to apply the configuration.
## Available Tools
### Sandbox Management
- **Create Sandbox**
- Creates a new Daytona sandbox
- Parameters:
- `name`: Name of the sandbox (optional)
- `target` (default: "us"): Target region
- `snapshot`: Snapshot for the sandbox (optional)
- `auto_stop_interval` (default: "15"): Auto-stop interval in minutes (0 disables)
- `auto_archive_interval` (default: "10080"): Auto-archive interval in minutes (0 means the maximum interval will be used)
- `auto_delete_interval` (default: "-1"): Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)
- `volumes`: Volumes to attach to the sandbox (optional)
- `network_block_all`: Whether to block all network access for the sandbox (optional)
- `network_allow_list`: Comma-separated list of allowed CIDR network addresses for the sandbox (optional)
- `public`: Whether the sandbox http preview is publicly accessible (optional)
- `cpu`: CPU cores allocated to the sandbox (optional)
- `gpu`: GPU units allocated to the sandbox (optional)
- `memory`: Memory allocated to the sandbox in GB (optional)
- `disk`: Disk space allocated to the sandbox in GB (optional)
- `user`: User associated with the sandbox (optional)
- `build_info`: Build information for the sandbox (optional)
- `env`: Environment variables for the sandbox (optional)
- `labels`: Labels for the sandbox (optional)
- **Destroy Sandbox**
- Removes an existing Daytona sandbox
- Parameters:
- `id`: ID of the sandbox to destroy
### File Operations
- **Download File**
- Downloads a file from the Daytona sandbox
- Returns content as text or base64 encoded image
- Parameters:
- `id`: ID of the sandbox to download the file from
- `file_path`: Path to the file
- **Upload File**
- Uploads a file to the Daytona sandbox
- Supports text or base64-encoded binary content
- Creates necessary parent directories automatically
- Files persist during the session with appropriate permissions
- Supports overwrite controls and maintains original file formats
- Parameters:
- `id`: ID of the sandbox to upload the file to
- `file_path`: Path to the file to upload
- `content`: Content of the file to upload
- `encoding`: Encoding of the file to upload
- `overwrite`: Overwrite the file if it already exists
- **Create Folder**
- Creates a new directory in the sandbox
- Parameters:
- `id`: ID of the sandbox to create the folder in
- `folder_path`: Path to create
- `mode`: Directory permissions (default: 0755)
- **Get File Info**
- Retrieves information about a file
- Parameters:
- `id`: ID of the sandbox to get the file information from
- `file_path`: Path to the file
- **List Files**
- Lists contents of a directory
- Parameters:
- `id`: ID of the sandbox to list the files from
- `path`: Directory path (defaults to current directory)
- **Move File**
- Moves or renames a file
- Parameters:
- `id`: ID of the sandbox to move the file in
- `source_path`: Source location
- `dest_path`: Destination location
- **Delete File**
- Removes a file or directory
- Parameters:
- `id`: ID of the sandbox to delete the file in
- `file_path`: Path to delete
### Preview
- **Preview Link**
- Generates accessible preview URLs for web applications
- Creates secure tunnels to expose local ports externally
- Validates server status on specified ports
- Provides diagnostic information for troubleshooting
- Supports custom descriptions and metadata for service organization
- Parameters:
- `id`: ID of the sandbox to preview the link from
- `port`: Port to expose
- `description`: Description of the service
- `check_server`: Check if a server is running on the port
### Git Operations
- **Git Clone**
- Clones a Git repository
- Parameters:
- `id`: ID of the sandbox to clone the repository in
- `url`: Repository URL
- `path`: Target directory (defaults to current)
- `branch`: Branch to clone
- `commit_id`: Specific commit to clone
- `username`: Git username
- `password`: Git password
### Command Execution
- **Execute Command**
- Runs shell commands in the Daytona environment
- Returns stdout, stderr, and exit code
- Commands run with sandbox user permissions
- Parameters:
- `id`: ID of the sandbox to execute the command in
- `command`: Command to execute
## Troubleshooting
Common issues and solutions:
- **Authentication Issues**
- Run `daytona login` to refresh credentials
- **Connection Errors**
- Verify MCP server configuration
- Check server status
- **Sandbox Errors**
- Use `daytona sandbox list` to check sandbox status
## Support
For additional assistance:
- Visit [daytona.io](https://daytona.io)
- Contact support at support@daytona.io
title: Network Limits (Firewall)
import { TabItem, Tabs } from '@astrojs/starlight/components'
Daytona provides network egress limiting for sandboxes to control internet access. This feature can be automatically applied based on your organization's billing tier or manually configured for specific sandboxes.
## Tier-Based Network Restrictions
Network limits are automatically applied to sandboxes based on your organization's billing tier. This provides secure and controlled internet access for development environments:
- **Tier 1 & Tier 2**: Network access is restricted and cannot be overridden at the sandbox level
- **Tier 3 & Tier 4**: Full internet access is available by default, with the ability to configure custom network settings
:::note
**Tier 1 & 2**: Organization-level network restrictions take precedence over sandbox-level settings. Even if you specify `networkAllowList` when creating a sandbox, the organization's network restrictions will still apply.
:::
To learn more about organization tiers and limits, see the [Limits documentation](/docs/limits/).
## Managing Network Access
### Creating Sandboxes with Network Restrictions
You can control network access when creating sandboxes using the `networkAllowList` and `networkBlockAll` parameters:
```python
from daytona import CreateSandboxFromSnapshotParams, Daytona
daytona = Daytona()
# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
network_allow_list='208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'
))
# Or block all network access
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
network_block_all=True
))
```
```typescript
import { Daytona } from '@daytonaio/sdk'
const daytona = new Daytona()
// Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)
const sandbox = await daytona.create({
networkAllowList: '208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'
})
// Or block all network access
const sandbox = await daytona.create({
networkBlockAll: true
})
```
:::note
If both `networkBlockAll` and `networkAllowList` are specified, `networkBlockAll` takes precedence and all network access will be blocked, ignoring the allow list.
:::
### Network Allow List Format
The `networkAllowList` accepts up to 5 CIDR network blocks separated by commas:
- **Single IP**: `208.80.154.232/32` (Wikipedia)
- **Subnet**: `192.168.1.0/24` (Private network)
- **Multiple networks**: `208.80.154.232/32,199.16.156.103/32,10.0.0.0/8`
:::note
**Essential Services**: Services that are essential for development are accessible on all tiers, including package registries, container registries, Git repositories, CDN services, platform services, system package managers etc.\
If you experience issues with any essential development services, please contact [support@daytona.io](mailto:support@daytona.io) for assistance as these should be accessible on all tiers.
For a complete list of whitelisted services, see [Essential Services](#essential-services) below.
:::
## Organization Configuration
The network access policies for your organization are set automatically depending on your organization's limits tier and cannot be modified by organization administrators. These policies determine the default network behavior for all sandboxes in your organization.
## Testing Network Access
To test network connectivity from your sandbox:
```bash
# Test HTTP connectivity to allowed addresses
curl -I https://208.80.154.232
# Test package manager access (allowed on all tiers)
apt update # For Ubuntu/Debian
npm ping # For Node.js
pip install --dry-run requests # For Python
```
## Security Benefits
Network limits provide several security advantages:
- **Prevents data exfiltration** from sandboxes
- **Reduces attack surface** by limiting external connections
- **Complies with security policies** for development environments
- **Enables fine-grained control** over network access
:::caution
Enabling unrestricted network access may pose security risks when executing untrusted code. It is recommended to whitelist specific network addresses using `networkAllowList` or block all network access using `networkBlockAll` instead.
Test network connectivity before starting critical development work and consider upgrading your tier if you need access to many external services.
:::
## Essential Services
The following services are whitelisted and accessible on all tiers:
- Package registries:
- npm: `registry.npmjs.org`, `registry.npmjs.com`, `nodejs.org`, `nodesource.com`, `npm.pkg.github.com`
- yarn: `classic.yarnpkg.com`, `registry.yarnpkg.com`, `repo.yarnpkg.com`, `releases.yarnpkg.com`, `yarn.npmjs.org`, `yarnpkg.netlify.com`, `dl.yarnpkg.com`, `yarnpkg.com`
- PyPI: `pypi.org`, `pypi.python.org`, `files.pythonhosted.org`, `bootstrap.pypa.io`
- Maven: `repo1.maven.org`, `repo.maven.apache.org`
- Container registries:
- Docker: `download.docker.com`, `registry-1.docker.io`, `registry.docker.io`, `auth.docker.io`, `index.docker.io`, `hub.docker.com`, `docker.io`
- Google: `gcr.io`, `asia.gcr.io`, `eu.gcr.io`, `us.gcr.io`, `marketplace.gcr.io`, `registry.cloud.google.com`
- Microsoft: `mcr.microsoft.com`
- Quay: `quay.io`, `quay-registry.s3.amazonaws.com`
- Kubernetes: `registry.k8s.io`
- Git repositories:
- GitHub: `github.com`, `api.github.com`, `raw.githubusercontent.com`, `github-releases.githubusercontent.com`, `codeload.github.com`, `ghcr.io`, `packages.github.com`
- GitLab: `gitlab.com`, `registry.gitlab.com`
- Bitbucket: `bitbucket.org`
- System package managers:
- Ubuntu: `archive.ubuntu.com`, `security.ubuntu.com`
- Debian: `deb.debian.org`, `security.debian.org`, `cdn-fastly.deb.debian.org`, `ftp.debian.org`
- CDN services:
- Cloudflare: `cloudflare.com`
- Fastly: `fastly.com`
- JavaScript CDNs: `unpkg.com`, `jsdelivr.net`
- AI/ML services:
- Anthropic: `api.anthropic.com`
- Platform services:
- Daytona: `app.daytona.io`
## Getting Help
If you encounter network access issues or need unrestricted network access
1. Check your **organization tier** in the [Dashboard](https://app.daytona.io/dashboard/limits)
2. Upgrade your **organization tier** by completing the required verification steps to unlock higher limits tiers automatically
3. Verify your **network allow list** configuration
4. Contact support at [support@daytona.io](mailto:support@daytona.io) for assistance
title: Organizations
import { TabItem, Tabs } from '@astrojs/starlight/components'
Organizations in Daytona are used to group resources and enable collaboration. Users can work individually in their Personal Organization or together in a Collaborative Organization.
### Personal vs Collaborative Organizations
Every Daytona user starts with a **Personal Organization**, ideal for solo use and experimentation. **Collaborative Organizations** are created manually and designed for company-wide collaboration with shared access and controls.
| Feature | Personal Organization | Collaborative Organization |
| ------------------ | -------------------------------- | ---------------------------------------------- |
| **Creation** | Automatic on signup | Manually by a user |
| **Members** | Single user only | Multiple users (invite-based) |
| **Access Control** | No roles or permissions | Roles with granular resource-based Assignments |
| **Billing** | Tied to individual user | Shared across team members |
| **Use Case** | Personal testing, small projects | Company/team development and production |
| **Quota Scope** | Per user | Shared across all members |
| **Deletable** | ❌ No | ✅ Yes (by Owner) |
Users can switch between their Personal and Collaborative Organizations using the dropdown in the sidebar. Each Organization has its own sandboxes, API keys, and resource quotas.
## Managing Members
### Organization Roles
Users within an Organization can have one of two different Roles:
- **Owners** have full
administrative access to the Organization and its resources. Organization Owners can perform administrative actions such as:
- **Members** have no administrative access
to the Organization, while their access to Organization resources is based on [**Assignments**](#available-assignments).
### Administrative Actions
Organization Owners can perform administrative actions such as:
- [Invite new users to the Organization](#inviting-new-users)
- [Manage pending invitations](#managing-invitations)
- Change [Role](#organization-roles) of a user in the Organization
- Update [Assignments](#available-assignments) for an Organization Member
- Remove user from the Organization
- Inspect audit logs
- [Delete Organization](#organization-settings)
### Inviting New Users
As an Organization **Owner**, to invite a new user to your Organization:
1. Navigate to the _Members page_.
2. Click on _Invite Member_.
3. Enter the email address of the user you want to invite.
4. Choose a [Role](#organization-roles) for the new user. If you select the `Member` role, define their [Assignments](#available-assignments).
### Available Assignments
The list of available **Assignments** includes:
| Assignment | Description |
| ----------------------- | ------------------------------------------------------------------- |
| **`Viewer (required)`** | Grants read access to all resources in the organization |
| **`Developer`** | Grants the ability to create sandboxes and keys in the organization |
| **`Sandboxes Admin`** | Grants admin access to sandboxes in the organization |
| **`Snapshots Admin`** | Grants admin access to snapshots in the organization |
| **`Registries Admin`** | Grants admin access to registries in the organization |
| **`Volumes Admin`** | Grants admin access to volumes in the organization |
| **`Super Admin`** | Grants full access to all resources in the organization |
| **`Auditor`** | Grants access to audit logs in the organization |
### Managing Invitations
To view their pending invitations to join other Organizations, users can navigate to the _Invitations
page_ by expanding the dropdown at the bottom of the sidebar, and clicking on _Invitations_. Once a user
accepts an invitation to join an Organization, they get access to resource quotas assigned to that
Organization and they may proceed by issuing a new [API key](/docs/en/api-keys) and creating sandboxes.
## Organization Settings
The [Settings](https://app.daytona.io/dashboard/settings) subpage in the Dashboard allows you to view the Organization ID and Name and to delete the Organization if you don't need it anymore. This action is irreversible, so please proceed with caution. Personal Organizations are there by default and cannot be deleted.
title: Open Source Deployment
This guide will walk you through running Daytona Open Source locally using Docker Compose.
The compose file can be found in the [docker](https://github.com/daytonaio/daytona/tree/main/docker) folder of the Daytona repository.
:::caution
- This setup is still in development and is **not safe to use in production**
- A separate deployment guide will be provided for production scenarios
:::
## Overview
The Docker Compose configuration includes all the necessary services to run Daytona:
- **API**: Main Daytona application server
- **Proxy**: Request proxy service
- **Runner**: Service that hosts the Daytona Runner
- **SSH Gateway**: Service that handles sandbox SSH access
- **Database**: PostgreSQL database for data persistence
- **Redis**: In-memory data store for caching and sessions
- **Dex**: OIDC authentication provider
- **Registry**: Docker image registry with web UI
- **MinIO**: S3-compatible object storage
- **MailDev**: Email testing service
- **Jaeger**: Distributed tracing
- **PgAdmin**: Database administration interface
## Quick Start
1. Clone the [Daytona repository](https://github.com/daytonaio/daytona)
2. [Install Docker and Docker Compose](https://docs.docker.com/get-docker/)
3. Run the following command (from the root of the Daytona repo) to start all services:
```bash
docker compose -f docker/docker-compose.yaml up -d
```
4. Access the services:
- Daytona Dashboard: http://localhost:3000
- Access Credentials: dev@daytona.io `password`
- Make sure that the default snapshot is active at http://localhost:3000/dashboard/snapshots
- PgAdmin: http://localhost:5050
- Registry UI: http://localhost:5100
- MinIO Console: http://localhost:9001 (minioadmin / minioadmin)
## DNS Setup for Proxy URLs
For local development, you need to resolve `*.proxy.localhost` domains to `127.0.0.1`:
```bash
./scripts/setup-proxy-dns.sh
```
This configures dnsmasq with `address=/proxy.localhost/127.0.0.1`.
**Without this setup**, SDK examples and direct proxy access won't work.
## Development Notes
- The setup uses shared networking for simplified service communication
- Database and storage data is persisted in Docker volumes
- The registry is configured to allow image deletion for testing
- Sandbox resource limits are disabled due to inability to partition cgroups in DinD environment where the sock is not mounted
## Additional Network Options
### HTTP Proxy
To configurate an outbound HTTP proxy for the Daytona services, you can set the following environment variables in the `docker-compose.yaml` file for each service that requires proxy access (the API service is the only that requires outbound access to pull images):
- `HTTP_PROXY`: URL of the HTTP proxy server
- `HTTPS_PROXY`: URL of the HTTPS proxy server
- `NO_PROXY`: Comma-separated list of hostnames or IP addresses that should bypass the proxy
The baseline configuration for the API service should be as follows:
```yaml
environment:
- HTTP_PROXY=
- HTTPS_PROXY=
- NO_PROXY=localhost,runner,dex,registry,minio,jaeger,otel-collector,
```
### Extra CA Certificates
To configure extra CA certificates (for example, paired with `DB_TLS` env vars), set the following environment variable in the API service:
```yaml
environment:
- NODE_EXTRA_CA_CERTS=/path/to/your/cert-bundle.pembundle
```
The provided file is a cert bundle. Meaning it can contain multiple CA certificates in PEM format.
## Environment Variables
You can customize the deployment by modifying environment variables in the `docker-compose.yaml` file.
Below is a full list of environment variables with their default values:
### API Service
| Variable | Type | Default Value | Description |
| ------------------------------------------ | ------- | ---------------------------------------------------- | ------------------------------------------- |
| `PORT` | number | `3000` | API service port |
| `DB_HOST` | string | `db` | PostgreSQL database hostname |
| `DB_PORT` | number | `5432` | PostgreSQL database port |
| `DB_USERNAME` | string | `user` | PostgreSQL database username |
| `DB_PASSWORD` | string | `pass` | PostgreSQL database password |
| `DB_DATABASE` | string | `daytona` | PostgreSQL database name |
| `DB_TLS_ENABLED` | boolean | `false` | Enable TLS for database connection |
| `DB_TLS_REJECT_UNAUTHORIZED` | boolean | `true` | Reject unauthorized TLS certificates |
| `REDIS_HOST` | string | `redis` | Redis server hostname |
| `REDIS_PORT` | number | `6379` | Redis server port |
| `OIDC_CLIENT_ID` | string | `daytona` | OIDC client identifier |
| `OIDC_ISSUER_BASE_URL` | string | `http://dex:5556/dex` | OIDC issuer base URL |
| `PUBLIC_OIDC_DOMAIN` | string | `http://localhost:5556/dex` | Public OIDC domain |
| `OIDC_AUDIENCE` | string | `daytona` | OIDC audience identifier |
| `OIDC_MANAGEMENT_API_ENABLED` | boolean | (empty) | Enable OIDC management API |
| `OIDC_MANAGEMENT_API_CLIENT_ID` | string | (empty) | OIDC management API client ID |
| `OIDC_MANAGEMENT_API_CLIENT_SECRET` | string | (empty) | OIDC management API client secret |
| `OIDC_MANAGEMENT_API_AUDIENCE` | string | (empty) | OIDC management API audience |
| `DEFAULT_SNAPSHOT` | string | `daytonaio/sandbox:0.4.3` | Default sandbox snapshot image |
| `DASHBOARD_URL` | string | `http://localhost:3000/dashboard` | Dashboard URL |
| `DASHBOARD_BASE_API_URL` | string | `http://localhost:3000` | Dashboard base API URL |
| `POSTHOG_API_KEY` | string | `phc_bYtEsdMDrNLydXPD4tufkBrHKgfO2zbycM30LOowYNv` | PostHog API key for analytics |
| `POSTHOG_HOST` | string | `https://d18ag4dodbta3l.cloudfront.net` | PostHog host URL |
| `POSTHOG_ENVIRONMENT` | string | `local` | PostHog environment identifier |
| `TRANSIENT_REGISTRY_URL` | string | `http://registry:6000` | Transient registry URL |
| `TRANSIENT_REGISTRY_ADMIN` | string | `admin` | Transient registry admin username |
| `TRANSIENT_REGISTRY_PASSWORD` | string | `password` | Transient registry admin password |
| `TRANSIENT_REGISTRY_PROJECT_ID` | string | `daytona` | Transient registry project ID |
| `INTERNAL_REGISTRY_URL` | string | `http://registry:6000` | Internal registry URL |
| `INTERNAL_REGISTRY_ADMIN` | string | `admin` | Internal registry admin username |
| `INTERNAL_REGISTRY_PASSWORD` | string | `password` | Internal registry admin password |
| `INTERNAL_REGISTRY_PROJECT_ID` | string | `daytona` | Internal registry project ID |
| `SMTP_HOST` | string | `maildev` | SMTP server hostname |
| `SMTP_PORT` | number | `1025` | SMTP server port |
| `SMTP_USER` | string | (empty) | SMTP username |
| `SMTP_PASSWORD` | string | (empty) | SMTP password |
| `SMTP_SECURE` | boolean | (empty) | Enable SMTP secure connection |
| `SMTP_EMAIL_FROM` | string | `"Daytona Team "` | SMTP sender email address |
| `S3_ENDPOINT` | string | `http://minio:9000` | S3-compatible storage endpoint |
| `S3_STS_ENDPOINT` | string | `http://minio:9000/minio/v1/assume-role` | S3 STS endpoint |
| `S3_REGION` | string | `us-east-1` | S3 region |
| `S3_ACCESS_KEY` | string | `minioadmin` | S3 access key |
| `S3_SECRET_KEY` | string | `minioadmin` | S3 secret key |
| `S3_DEFAULT_BUCKET` | string | `daytona` | S3 default bucket name |
| `S3_ACCOUNT_ID` | string | `/` | S3 account ID |
| `S3_ROLE_NAME` | string | `/` | S3 role name |
| `ENVIRONMENT` | string | `dev` | Application environment |
| `MAX_AUTO_ARCHIVE_INTERVAL` | number | `43200` | Maximum auto-archive interval (seconds) |
| `OTEL_ENABLED` | boolean | `true` | Enable OpenTelemetry tracing |
| `OTEL_COLLECTOR_URL` | string | `http://jaeger:4318/v1/traces` | OpenTelemetry collector URL |
| `MAINTENANCE_MODE` | boolean | `false` | Enable maintenance mode |
| `PROXY_DOMAIN` | string | `proxy.localhost:4000` | Proxy domain |
| `PROXY_PROTOCOL` | string | `http` | Proxy protocol |
| `PROXY_API_KEY` | string | `super_secret_key` | Proxy API key |
| `PROXY_TEMPLATE_URL` | string | `http://{{PORT}}-{{sandboxId}}.proxy.localhost:4000` | Proxy template URL pattern |
| `DEFAULT_RUNNER_DOMAIN` | string | `runner:3003` | Default runner domain |
| `DEFAULT_RUNNER_API_URL` | string | `http://runner:3003` | Default runner API URL |
| `DEFAULT_RUNNER_PROXY_URL` | string | `http://runner:3003` | Default runner proxy URL |
| `DEFAULT_RUNNER_API_KEY` | string | `secret_api_token` | Default runner API key |
| `DEFAULT_RUNNER_CPU` | number | `4` | Default runner CPU allocation |
| `DEFAULT_RUNNER_MEMORY` | number | `8` | Default runner memory allocation (GB) |
| `DEFAULT_RUNNER_DISK` | number | `50` | Default runner disk allocation (GB) |
| `DEFAULT_RUNNER_GPU` | number | `0` | Default runner GPU allocation |
| `DEFAULT_RUNNER_GPU_TYPE` | string | `none` | Default runner GPU type |
| `DEFAULT_RUNNER_CAPACITY` | number | `100` | Default runner capacity |
| `DEFAULT_RUNNER_REGION` | string | `us` | Default runner region |
| `DEFAULT_RUNNER_CLASS` | string | `small` | Default runner class |
| `DEFAULT_ORG_QUOTA_TOTAL_CPU_QUOTA` | number | `10000` | Default organization total CPU quota |
| `DEFAULT_ORG_QUOTA_TOTAL_MEMORY_QUOTA` | number | `10000` | Default organization total memory quota |
| `DEFAULT_ORG_QUOTA_TOTAL_DISK_QUOTA` | number | `100000` | Default organization total disk quota |
| `DEFAULT_ORG_QUOTA_MAX_CPU_PER_SANDBOX` | number | `100` | Default organization max CPU per sandbox |
| `DEFAULT_ORG_QUOTA_MAX_MEMORY_PER_SANDBOX` | number | `100` | Default organization max memory per sandbox |
| `DEFAULT_ORG_QUOTA_MAX_DISK_PER_SANDBOX` | number | `1000` | Default organization max disk per sandbox |
| `DEFAULT_ORG_QUOTA_SNAPSHOT_QUOTA` | number | `1000` | Default organization snapshot quota |
| `DEFAULT_ORG_QUOTA_MAX_SNAPSHOT_SIZE` | number | `1000` | Default organization max snapshot size |
| `DEFAULT_ORG_QUOTA_VOLUME_QUOTA` | number | `10000` | Default organization volume quota |
| `SSH_GATEWAY_API_KEY` | string | `ssh_secret_api_token` | SSH gateway API key |
| `SSH_GATEWAY_COMMAND` | string | `ssh -p 2222 {{TOKEN}}@localhost` | SSH gateway command template |
| `RUNNER_DECLARATIVE_BUILD_SCORE_THRESHOLD` | number | `10` | Runner declarative build score threshold |
| `RUNNER_AVAILABILITY_SCORE_THRESHOLD` | number | `10` | Runner availability score threshold |
| `RUN_MIGRATIONS` | boolean | `true` | Enable database migrations on startup |
### Runner
| Variable | Type | Default Value | Description |
| -------------------------- | ------- | --------------------------------- | ------------------------------------- |
| `VERSION` | string | `0.0.1` | Runner service version |
| `ENVIRONMENT` | string | `development` | Application environment |
| `API_PORT` | number | `3003` | Runner API service port |
| `API_TOKEN` | string | `secret_api_token` | Runner API authentication token |
| `LOG_FILE_PATH` | string | `/home/daytona/runner/runner.log` | Path to runner log file |
| `RESOURCE_LIMITS_DISABLED` | boolean | `true` | Disable resource limits for sandboxes |
| `AWS_ENDPOINT_URL` | string | `http://minio:9000` | AWS S3-compatible storage endpoint |
| `AWS_REGION` | string | `us-east-1` | AWS region |
| `AWS_ACCESS_KEY_ID` | string | `minioadmin` | AWS access key ID |
| `AWS_SECRET_ACCESS_KEY` | string | `minioadmin` | AWS secret access key |
| `AWS_DEFAULT_BUCKET` | string | `daytona` | AWS default bucket name |
| `SERVER_URL` | string | `http://api:3000/api` | Daytona API server URL |
### SSH Gateway
| Variable | Type | Default Value | Description |
| ------------------ | ------ | ------------------------------------ | -------------------------- |
| `API_URL` | string | `http://api:3000/api` | Daytona API URL |
| `API_KEY` | string | `ssh_secret_api_token` | API authentication key |
| `SSH_PRIVATE_KEY` | string | (Base64-encoded OpenSSH private key) | SSH private key for auth |
| `SSH_HOST_KEY` | string | (Base64-encoded OpenSSH host key) | SSH host key for server |
| `SSH_GATEWAY_PORT` | number | `2222` | SSH gateway listening port |
### Proxy
| Variable | Type | Default Value | Description |
| -------------------- | ------ | --------------------------- | ------------------------------ |
| `DAYTONA_API_URL` | string | `http://api:3000/api` | Daytona API URL |
| `PROXY_PORT` | number | `4000` | Proxy service port |
| `PROXY_DOMAIN` | string | `proxy.localhost:4000` | Proxy domain |
| `PROXY_API_KEY` | string | `super_secret_key` | Proxy API authentication key |
| `PROXY_PROTOCOL` | string | `http` | Proxy protocol (http or https) |
| `OIDC_CLIENT_ID` | string | `daytona` | OIDC client identifier |
| `OIDC_CLIENT_SECRET` | string | (empty) | OIDC client secret |
| `OIDC_DOMAIN` | string | `http://dex:5556/dex` | OIDC domain |
| `OIDC_PUBLIC_DOMAIN` | string | `http://localhost:5556/dex` | OIDC public domain |
| `OIDC_AUDIENCE` | string | `daytona` | OIDC audience identifier |
| `REDIS_HOST` | string | `redis` | Redis server hostname |
| `REDIS_PORT` | number | `6379` | Redis server port |
## [OPTIONAL] Configure Auth0 for Authentication
The default compose setup uses a local Dex OIDC provider for authentication. However, you can configure Auth0 as an alternative OIDC provider by following these steps:
### Step 1: Create Your Auth0 Tenant
Begin by navigating to https://auth0.com/signup and start the signup process. Choose your account type based on your use case - select `Company` for business applications or `Personal` for individual projects.\
On the "Let's get setup" page, you'll need to enter your application name such as `My Daytona` and select `Single Page Application (SPA)` as the application type. For authentication methods, you can start with `Email and Password` since additional social providers like Google, GitHub, or Facebook can be added later. Once you've configured these settings, click `Create Application` in the bottom right corner.
### Step 2: Configure Your Single Page Application
Navigate to `Applications` > `Applications` in the left sidebar and select the application you just created. Click the `Settings` tab and scroll down to find the `Application URIs` section where you'll configure the callback and origin URLs.
In the `Allowed Callback URIs` field, add the following URLs:
```
http://localhost:3000
http://localhost:3000/api/oauth2-redirect.html
http://localhost:4000/callback
http://proxy.localhost:4000/callback
```
For `Allowed Logout URIs`, add:
```
http://localhost:3000
```
And for `Allowed Web Origins`, add:
```
http://localhost:3000
```
Remember to click `Save Changes` at the bottom of the page to apply these configurations.
### Step 3: Create Machine-to-Machine Application
You'll need a Machine-to-Machine application to interact with Auth0's Management API. Go to `Applications` > `Applications` and click `Create Application`. Choose `Machine to Machine Applications` as the type and provide a descriptive name like `My Management API M2M`.
After creating the application, navigate to the `APIs` tab within your new M2M application. Find and authorize the `Auth0 Management API` by clicking the toggle or authorize button.\
Once authorized, click the dropdown arrow next to the Management API to configure permissions. Grant the following permissions to your M2M application:
```
read:users
update:users
read:connections
create:guardian_enrollment_tickets
read:connections_options
```
Click `Save` to apply these permission changes.
### Step 4: Set Up Custom API
Your Daytona application will need a custom API to handle authentication and authorization. Navigate to `Applications` > `APIs` in the left sidebar and click `Create API`. Enter a descriptive name such as `My Daytona API` and provide an identifier like `my-daytona-api`. The identifier should be a unique string that will be used in your application configuration.\
After creating the API, go to the `Permissions` tab to define the scopes your application will use. Add each of the following permissions with their corresponding descriptions:
| Permission | Description |
| --------------------------- | ---------------------------------------- |
| `read:node` | Get workspace node info |
| `create:node` | Create new workspace node record |
| `create:user` | Create user account |
| `read:users` | Get all user accounts |
| `regenerate-key-pair:users` | Regenerate user SSH key-pair |
| `read:workspaces` | Read workspaces (user scope) |
| `create:registry` | Create a new docker registry auth record |
| `read:registries` | Get all docker registry records |
| `read:registry` | Get docker registry record |
| `write:registry` | Create or update docker registry record |
### Step 5: Configure Environment Variables
Once you've completed all the Auth0 setup steps, you'll need to configure environment variables in your Daytona deployment. These variables connect your application to the Auth0 services you've just configured.
#### Finding Your Configuration Values
You can find the necessary values in the Auth0 dashboard. For your SPA application settings, go to `Applications` > `Applications`, select your SPA app, and click the `Settings` tab. For your M2M application, follow the same path but select your Machine-to-Machine app instead. Custom API settings are located under `Applications` > `APIs`, then select your custom API and go to `Settings`.
#### API Service Configuration
Configure the following environment variables for your API service:
```bash
OIDC_CLIENT_ID=your_spa_app_client_id
OIDC_ISSUER_BASE_URL=your_spa_app_domain
OIDC_AUDIENCE=your_custom_api_identifier
OIDC_MANAGEMENT_API_ENABLED=true
OIDC_MANAGEMENT_API_CLIENT_ID=your_m2m_app_client_id
OIDC_MANAGEMENT_API_CLIENT_SECRET=your_m2m_app_client_secret
OIDC_MANAGEMENT_API_AUDIENCE=your_auth0_managment_api_identifier
```
#### Proxy Service Configuration
For your proxy service, configure these environment variables:
```bash
OIDC_CLIENT_ID=your_spa_app_client_id
OIDC_CLIENT_SECRET=
OIDC_DOMAIN=your_spa_app_domain
OIDC_AUDIENCE=your_custom_api_identifier (with trailing slash)
```
Note that `OIDC_CLIENT_SECRET` should remain empty for your proxy environment.
title: Preview & Authentication
import { Tabs, TabItem } from '@astrojs/starlight/components'
The Daytona SDK provides a method to generate preview links for Sandboxes. A preview link's schema consists of the port and Sandbox ID (e.g.
`https://3000-sandboxid.proxy.daytona.works`).
Any process listening for HTTP traffic on ports 3000–9999 can be previewed.
## Fetching a Preview Link
To fetch the preview link and the authorization token for a specific port, you can simply use the SDK method:
```python
preview_info = sandbox.get_preview_link(3000)
print(f"Preview link url: {preview_info.url}")
print(f"Preview link token: {preview_info.token}")
```
```typescript
const previewInfo = await sandbox.getPreviewUrl(3000);
console.log(`Preview link url: ${previewInfo.url}`);
console.log(`Preview link token: ${previewInfo.token}`);
```
:::tip
If you want to serve the previews under your own domain instead of using Daytona's URLs, check out the [Custom Domain/Authentication](/docs/en/custom-domain-authentication) section.
:::
See: [get_preview_link (Python SDK)](/docs/python-sdk/sync/sandbox/#sandboxget_preview_link), [getPreviewLink (TypeScript SDK)](/docs/typescript-sdk/sandbox/#getpreviewlink)
## Authentication
If the Sandbox has its `public` property set to `true`, these links will be publicly accessible, otherwise the preview link will be available only to the Sandbox Organization users.
For programmatic access, use the authorization token to access the preview URL:
```bash
curl -H "x-daytona-preview-token: vg5c0ylmcimr8b_v1ne0u6mdnvit6gc0" \
https://3000-sandbox-123456.proxy.daytona.work
```
## Warning Page
When opening the preview link in a browser, a warning page will be shown for the first time.
This warning serves as a security measure to inform users about the potential risks of visiting the preview URL.
The warning page will only be shown when loading the preview link in a browser.
To avoid this warning you can do one of the following:
- Send the `X-Daytona-Skip-Preview-Warning: true` header
- Upgrade to [Tier 3](/docs/en/limits)
- Deploy your own [custom preview proxy](/docs/en/custom-domain-authentication)
title: Process and Code Execution
import { Tabs, TabItem } from '@astrojs/starlight/components';
The Daytona SDK provides powerful process and code execution capabilities through the `process` module in Sandboxes. This guide covers all available process operations and best practices.
## Code Execution
Daytona SDK provides an option to execute code in Python and TypeScript.
### Running Code
Daytona SDK provides an option to run code snippets in Python and TypeScript. You can execute code with input, timeout, and environment variables.
```python
# Run Python code
response = sandbox.process.code_run('''
def greet(name):
return f"Hello, {name}!"
print(greet("Daytona"))
''')
print(response.result)
```
```typescript
// Run TypeScript code
let response = await sandbox.process.codeRun(`
function greet(name: string): string {
return \`Hello, \${name}!\`;
}
console.log(greet("Daytona"));
`);
console.log(response.result);
// Run code with argv and environment variables
response = await sandbox.process.codeRun(
`
console.log(\`Hello, \${process.argv[2]}!\`);
console.log(\`FOO: \${process.env.FOO}\`);
`,
{
argv: ["Daytona"],
env: { FOO: "BAR" }
}
);
console.log(response.result);
// Run code with timeout
response = await sandbox.process.codeRun(
'setTimeout(() => console.log("Done"), 2000);',
undefined,
5000
);
console.log(response.result);
```
See: [code_run (Python SDK)](/docs/python-sdk/sync/process/#processcode_run), [codeRun (TypeScript SDK)](/docs/typescript-sdk/process/#coderun)
## Process Execution
Daytona SDK provides an option to execute shell commands and manage background processes in Sandboxes. The workDir for executing defaults to the current Sandbox working directory. Uses the WORKDIR specified in
the Dockerfile if present, or falling back to the user's home directory if not - e.g. `workspace/repo` implies `/my-work-dir/workspace/repo`, but you can override it with an absolute path (by starting the path with `/`).
### Running Commands
Daytona SDK provides an option to execute shell commands in Python and TypeScript. You can run commands with input, timeout, and environment variables.
```python
# Execute any shell command
response = sandbox.process.exec("ls -la")
print(response.result)
# Setting a working directory and a timeout
response = sandbox.process.exec("sleep 3", cwd="workspace/src", timeout=5)
print(response.result)
# Passing environment variables
response = sandbox.process.exec("echo $CUSTOM_SECRET", env={
"CUSTOM_SECRET": "DAYTONA"
}
)
print(response.result)
```
```typescript
// Execute any shell command
const response = await sandbox.process.executeCommand("ls -la");
console.log(response.result);
// Setting a working directory and a timeout
const response2 = await sandbox.process.executeCommand("sleep 3", "workspace/src", undefined, 5);
console.log(response2.result);
// Passing environment variables
const response3 = await sandbox.process.executeCommand("echo $CUSTOM_SECRET", ".", {
"CUSTOM_SECRET": "DAYTONA"
}
);
console.log(response3.result);
```
See: [exec (Python SDK)](/docs/python-sdk/sync/process/#processexec), [executeCommand (TypeScript SDK)](/docs/typescript-sdk/process/#executecommand)
## Sessions (Background Processes)
Daytona SDK provides an option to start, stop, and manage background process sessions in Sandboxes. You can run long-running commands, monitor process status, and list all running processes.
### Managing Long-Running Processes
Daytona SDK provides an option to start and stop background processes. You can run long-running commands and monitor process status.
```python
# Check session's executed commands
session = sandbox.process.get_session(session_id)
print(f"Session {process_id}:")
for command in session.commands:
print(f"Command: {command.command}, Exit Code: {command.exit_code}")
# List all running sessions
sessions = sandbox.process.list_sessions()
for session in sessions:
print(f"PID: {session.id}, Commands: {session.commands}")
```
```typescript
// Check session's executed commands
const session = await sandbox.process.getSession(sessionId);
console.log(`Session ${sessionId}:`);
for (const command of session.commands) {
console.log(`Command: ${command.command}, Exit Code: ${command.exitCode}`);
}
// List all running sessions
const sessions = await sandbox.process.listSessions();
for (const session of sessions) {
console.log(`PID: ${session.id}, Commands: ${session.commands}`);
}
```
See: [get_session (Python SDK)](/docs/python-sdk/sync/process/#processget_session), [list_sessions (Python SDK)](/docs/python-sdk/sync/process/#processlist_sessions), [getSession (TypeScript SDK)](/docs/typescript-sdk/process/#getsession), [listSessions (TypeScript SDK)](/docs/typescript-sdk/process/#listsessions)
## Best Practices
Use the following best practices when working with process and code execution in Daytona SDK.
### Resource Management
The following best practices apply to managing resources when executing processes:
1. Use [sessions](#sessions-background-processes) for long-running operations
2. Clean up sessions after execution
3. Handle session exceptions properly
```python
# Python - Clean up session
session_id = "long-running-cmd"
try:
sandbox.process.create_session(session_id)
session = sandbox.process.get_session(session_id)
# Do work...
finally:
sandbox.process.delete_session(session.session_id)
```
```typescript
// TypeScript - Clean up session
const sessionId = "long-running-cmd";
try {
await sandbox.process.createSession(sessionId);
const session = await sandbox.process.getSession(sessionId);
// Do work...
} finally {
await sandbox.process.deleteSession(session.sessionId);
}
```
See: [create_session (Python SDK)](/docs/python-sdk/sync/process/#processcreate_session), [delete_session (Python SDK)](/docs/python-sdk/sync/process/#processdelete_session), [createSession (TypeScript SDK)](/docs/typescript-sdk/process/#createsession), [deleteSession (TypeScript SDK)](/docs/typescript-sdk/process/#deletesession)
### Error Handling
The following best practices apply to error handling when executing processes:
- Handle process exceptions properly
- Log error details for debugging
- Use try-catch blocks for error handling
```python
try:
response = sandbox.process.code_run("invalid python code")
except ProcessExecutionError as e:
print(f"Execution failed: {e}")
print(f"Exit code: {e.exit_code}")
print(f"Error output: {e.stderr}")
```
```typescript
try {
const response = await sandbox.process.codeRun("invalid typescript code");
} catch (e) {
if (e instanceof ProcessExecutionError) {
console.error("Execution failed:", e);
console.error("Exit code:", e.exitCode);
console.error("Error output:", e.stderr);
}
}
```
## Common Issues
To troubleshoot common issues related to process and code execution, refer to the following table:
| Issue | Solutions |
|-------|-----------|
| `Process Execution Failed` | • Check command syntax • Verify required dependencies • Ensure sufficient permissions |
| `Process Timeout` | • Adjust timeout settings • Optimize long-running operations • Consider using background processes |
| `Resource Limits` | • Monitor process memory usage • Handle process cleanup properly • Use appropriate resource constraints |
title: Pseudo Terminal (PTY)
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona SDK provides powerful pseudo terminal (PTY) capabilities through the `process` module in Sandboxes. PTY sessions allow you to create interactive terminal sessions that can execute commands, handle user input, and manage terminal operations.
## What is PTY?
A PTY (Pseudo Terminal) is a virtual terminal interface that allows programs to interact with a shell as if they were connected to a real terminal. PTY sessions in Daytona enable:
- Interactive command execution with real-time input/output
- Terminal resizing capabilities
- Process management with kill operations
- Real-time data streaming from terminal sessions
## Interactive Commands with PTY
PTY sessions excel at handling interactive commands that require user input and can be resized during execution.
```python
import time
from daytona import Daytona, Sandbox
from daytona.common.pty import PtySize
def handle_pty_data(data: bytes):
text = data.decode("utf-8", errors="replace")
print(text, end="")
# Create PTY session
pty_handle = sandbox.process.create_pty_session(
id="interactive-session",
pty_size=PtySize(cols=300, rows=100)
)
# Send interactive command
pty_handle.send_input('printf "Are you accepting the terms and conditions? (y/n): " && read confirm && if [ "$confirm" = "y" ]; then echo "You accepted"; else echo "You did not accept"; fi\n')
time.sleep(1)
pty_handle.send_input("y\n")
# Resize terminal
pty_session_info = pty_handle.resize(PtySize(cols=210, rows=110))
print(f"PTY session resized to {pty_session_info.cols}x{pty_session_info.rows}")
# Exit the session
pty_handle.send_input('exit\n')
# Handle output using iterator
for data in pty_handle:
handle_pty_data(data)
print(f"Session completed with exit code: {pty_handle.exit_code}")
````
```typescript
import { Daytona, Sandbox } from '@daytonaio/sdk'
// Create PTY session
const ptyHandle = await sandbox.process.createPty({
id: 'interactive-session',
cols: 300,
rows: 100,
onData: (data) => {
const text = new TextDecoder().decode(data)
process.stdout.write(text)
},
})
await ptyHandle.waitForConnection()
// Send interactive command
await ptyHandle.sendInput('printf "Are you accepting the terms and conditions? (y/n): " && read confirm && if [ "$confirm" = "y" ]; then echo "You accepted"; else echo "You did not accept"; fi\n')
await new Promise(resolve => setTimeout(resolve, 1000))
await ptyHandle.sendInput('y\n')
// Resize terminal
const ptySessionInfo = await sandbox.process.resizePtySession(ptySessionId, 210, 110)
console.log(`\nPTY session resized to ${ptySessionInfo.cols}x${ptySessionInfo.rows}`)
// Exit the session
await ptyHandle.sendInput('exit\n')
// Wait for completion
const result = await ptyHandle.wait()
console.log(`Session completed with exit code: ${result.exitCode}`)
````
## Long-Running Processes with PTY
PTY sessions are perfect for managing long-running processes that need to be monitored or terminated.
```python
import time
from daytona import Daytona, Sandbox
from daytona.common.pty import PtySize
def handle_pty_data(data: bytes):
text = data.decode("utf-8", errors="replace")
print(text, end="")
# Create PTY session
pty_handle = sandbox.process.create_pty_session(
id="long-running-session",
pty_size=PtySize(cols=120, rows=30)
)
# Start a long-running process
pty_handle.send_input('while true; do echo "Running... $(date)"; sleep 1; done\n')
# Using thread and wait() method to handle PTY output
thread = threading.Thread(target=pty_handle.wait, args=(handle_pty_data, 10))
thread.start()
time.sleep(3) # Let it run for a bit
print("Killing long-running process...")
pty_handle.kill()
thread.join()
print(f"\nProcess terminated with exit code: {result.exit_code}")
if result.error:
print(f"Termination reason: {result.error}")
````
```typescript
import { Daytona, Sandbox } from '@daytonaio/sdk'
// Create PTY session
const ptyHandle = await sandbox.process.createPty({
id: 'long-running-session',
cols: 120,
rows: 30,
onData: (data) => {
const text = new TextDecoder().decode(data)
process.stdout.write(text)
},
})
await ptyHandle.waitForConnection()
// Start a long-running process
await ptyHandle.sendInput('while true; do echo "Running... $(date)"; sleep 1; done\n')
await new Promise(resolve => setTimeout(resolve, 3000)) // Let it run for a bit
console.log('Killing long-running process...')
await ptyHandle.kill()
// Wait for termination
const result = await ptyHandle.wait()
console.log(`\nProcess terminated with exit code: ${result.exitCode}`)
if (result.error) {
console.log(`Termination reason: ${result.error}`)
}
````
## Best Practices
### Resource Management
Always clean up PTY sessions to prevent resource leaks:
```python
# Python: Use try/finally
pty_handle = None
try:
pty_handle = sandbox.process.create_pty_session(id="session", pty_size=PtySize(cols=120, rows=30))
# Do work...
finally:
if pty_handle:
pty_handle.kill()
```
```typescript
// TypeScript: Use try/finally
let ptyHandle
try {
ptyHandle = await sandbox.process.createPty({
id: 'session',
cols: 120,
rows: 30,
})
// Do work...
} finally {
if (ptyHandle) await ptyHandle.kill()
}
```
### Error Handling
Monitor exit codes and handle errors appropriately:
```python
# Python: Check exit codes
result = pty_handle.wait()
if result.exit_code != 0:
print(f"Command failed: {result.exit_code}")
print(f"Error: {result.error}")
```
```typescript
// TypeScript: Check exit codes
const result = await ptyHandle.wait()
if (result.exitCode !== 0) {
console.log(`Command failed: ${result.exitCode}`)
console.log(`Error: ${result.error}`)
}
```
## Common Use Cases
- **Interactive Development**: REPLs, debuggers, and development tools
- **Build Processes**: Running and monitoring compilation, testing, or deployment
- **System Administration**: Remote server management and configuration
- **User Interfaces**: Terminal-based applications requiring user interaction
## Troubleshooting
**Connection Issues**: Verify sandbox status, network connectivity, and proper session IDs.
**Performance Issues**: Use appropriate terminal dimensions and efficient data handlers.
**Process Management**: Use explicit `kill()` calls and proper timeout handling for long-running processes.
title: Region Selection
import { TabItem, Tabs } from '@astrojs/starlight/components'
The Daytona SDK can be configured to run in multiple geographic regions. The following regions are currently available:
| Region | Target |
| ------------- | ---- |
| United States | `us` |
| Europe | `eu` |
The region is specificed by setting the `target` parameter on initialization:
```python
from daytona import Daytona, DaytonaConfig
# Configure Daytona to use the US region
config = DaytonaConfig(
target="us"
)
# Initialize the Daytona client with the specified configuration
daytona = Daytona(config)
```
```typescript
import { Daytona } from '@daytonaio/sdk';
// Configure Daytona to use the EU region
const daytona: Daytona = new Daytona({
target: "eu"
});
```
For more information, see [Configuration](/docs/configuration).
title: Sandbox Management
import { TabItem, Tabs } from '@astrojs/starlight/components'
import Image from 'astro/components/Image.astro'
Sandboxes are isolated development environments managed by Daytona. This guide covers how to create, manage, and remove Sandboxes using the SDK.
By default, Sandboxes auto-stop after 15 minutes of inactivity and use **1 vCPU**, **1GB RAM**, and **3GiB disk**.
## Sandbox Lifecycle
Throughout its lifecycle, a Daytona Sandbox can have several different states. The diagram below shows the states and possible transitions between them.
By default, sandboxes auto-stop after `15 minutes` of inactivity and auto-archive after `7 days` of being stopped. To keep the Sandbox running indefinitely without interruption, set the auto-stop value to `0` during creation.
## Creating Sandboxes
The Daytona SDK provides an option to create Sandboxes with default or custom configurations. You can specify the language, [Snapshot](/docs/en/snapshots), resources, environment variables, and volumes for the Sandbox.
Running Sandboxes utilize CPU, memory, and disk storage. Every resource is charged per second of usage.
:::tip
If you want to prolong the auto-stop interval, you can [set the auto-stop interval parameter](/docs/en/sandbox-management#auto-stop-interval) when creating a Sandbox.
:::
### Basic Sandbox Creation
The Daytona SDK provides methods to create Sandboxes with default configurations, specific languages, custom names, or custom labels using Python and TypeScript.
```python
from daytona import Daytona, CreateSandboxFromSnapshotParams
daytona = Daytona()
# Create a basic Sandbox
sandbox = daytona.create()
# Create a Sandbox with specific language
params = CreateSandboxFromSnapshotParams(language="python")
sandbox = daytona.create(params)
# Create a Sandbox with a custom name
params = CreateSandboxFromSnapshotParams(name="my-sandbox")
sandbox = daytona.create(params)
# Create a Sandbox with custom labels
params = CreateSandboxFromSnapshotParams(labels={"SOME_LABEL": "my-label"})
sandbox = daytona.create(params)
```
```typescript
import { Daytona } from '@daytonaio/sdk';
const daytona = new Daytona();
// Create a basic Sandbox
const sandbox = await daytona.create();
// Create a Sandbox with specific language
const sandbox = await daytona.create({ language: 'typescript' });
// Create a Sandbox with a custom name
const sandbox = await daytona.create({ name: 'my-sandbox' });
// Create a Sandbox with custom labels
const sandbox = await daytona.create({ labels: { SOME_LABEL: 'my-label' } });
```
:::note
**Sandbox Names**: You can specify a custom name for your sandbox using the `name` parameter. If not provided, the sandbox ID will be used as the name. Sandbox names are reusable - once a sandbox with a specific name is destroyed, that name becomes available for use again.
:::
See: [create (Python SDK)](/docs/en/python-sdk/sync/daytona#daytonacreate), [create (TypeScript SDK)](/docs/en/typescript-sdk/daytona#create)
When Sandboxes are not actively used, it is recommended that they be stopped. This can be done manually [using the stop command](/docs/en/sandbox-management#stop-and-start-sandbox) or automatically by [setting the auto-stop interval](/docs/en/sandbox-management#auto-stop-and-auto-archive).
:::note
Daytona keeps a pool of warm Sandboxes using default Snapshots.\
When available, your Sandbox will launch in milliseconds instead of cold-booting.
:::
### Sandbox Resources
Daytona Sandboxes come with **1 vCPU**, **1GB RAM**, and **3GiB disk** by default.
Use the `Resources` class to define exactly what you need: CPU, memory, and disk space are all customizable.
Organizations get a maximum Sandbox resource limit of 4 vCPUs, 8GB RAM, and 10GB disk. Need more power? Contact [support@daytona.io](mailto:support@daytona.io) and let us know your use case.
Check your available resources and limits in the [dashboard](https://app.daytona.io/dashboard/limits).
```python
from daytona import Daytona, Resources, CreateSandboxFromImageParams, Image
daytona = Daytona()
# Create a Sandbox with custom resources
resources = Resources(
cpu=2, # 2 CPU cores
memory=4, # 4GB RAM
disk=8, # 8GB disk space
)
params = CreateSandboxFromImageParams(
image=Image.debian_slim("3.12"),
resources=resources
)
sandbox = daytona.create(params)
```
```typescript
import { Daytona, Image } from "@daytonaio/sdk";
async function main() {
const daytona = new Daytona();
// Create a Sandbox with custom resources
const sandbox = await daytona.create({
image: Image.debianSlim("3.13"),
resources: {
cpu: 2, // 2 CPU cores
memory: 4, // 4GB RAM
disk: 8, // 8GB disk space
},
});
}
main();
```
:::note
All resource parameters are optional. If not specified, Daytona will use default values appropriate for the selected language and use case.
:::
### Ephemeral Sandboxes
Ephemeral Sandboxes are Sandboxes that are automatically deleted once they are stopped. They are useful for short-lived tasks or for testing purposes.
To create an ephemeral Sandbox, set `ephemeral` to `True` when creating a Sandbox:
```python
from daytona import Daytona, CreateSandboxFromSnapshotParams
daytona = Daytona()
# Create an ephemeral Sandbox
params = CreateSandboxFromSnapshotParams(
ephemeral=True,
auto_stop_interval=5 # the ephemeral sandbox will be deleted after 5 minutes of inactivity
)
sandbox = daytona.create(params)
```
```typescript
import { Daytona } from '@daytonaio/sdk';
const daytona = new Daytona();
// Create an ephemeral Sandbox
const sandbox = await daytona.create({
ephemeral: true,
autoStopInterval: 5 // the ephemeral sandbox will be deleted after 5 minutes of inactivity
});
```
:::note
Setting ["autoDeleteInterval: 0"](#auto-delete-interval) has the same effect as setting "ephemeral" to `true`.
:::
### Network Settings (Firewall)
Daytona Sandboxes provide configurable network firewall controls to enhance security and manage connectivity. By default, network access follows standard security policies, but you can customize network settings when creating a Sandbox.
Learn more about network limits in the [Network Limits](/docs/en/network-limits) documentation.
## Sandbox Information
The Daytona SDK provides methods to get information about a Sandbox, such as ID, root directory, and status using Python and TypeScript.
```python
# Get Sandbox ID
sandbox_id = sandbox.id
# Get the root directory of the Sandbox user
root_dir = sandbox.get_user_root_dir()
# Get the Sandbox id, auto-stop interval and state
print(sandbox.id)
print(sandbox.auto_stop_interval)
print(sandbox.state)
```
```typescript
// Get Sandbox ID
const sandboxId = sandbox.id;
// Get the root directory of the Sandbox user
const rootDir = await sandbox.getUserRootDir();
// Get the Sandbox id, auto-stop interval and state
console.log(sandbox.id)
console.log(sandbox.autoStopInterval)
console.log(sandbox.state)
```
To get the preview URL for a specific port, check out [Preview & Authentication](/docs/en/preview-and-authentication).
## Stop and Start Sandbox
The Daytona SDK provides methods to stop and start Sandboxes using Python and TypeScript.
Stopped Sandboxes maintain filesystem persistence while their memory state is cleared. They incur only disk usage costs and can be started again when needed.
```python
sandbox = daytona.create(CreateSandboxParams(language="python"))
# Stop Sandbox
sandbox.stop()
print(sandbox.id) # 7cd11133-96c1-4cc8-9baa-c757b8f8c916
# The sandbox ID can later be used to find the sandbox and start it
sandbox = daytona.find_one("7cd11133-96c1-4cc8-9baa-c757b8f8c916")
# Start Sandbox
sandbox.start()
```
```typescript
const sandbox = await daytona.create({ language: 'typescript' });
// Stop Sandbox
await sandbox.stop();
console.log(sandbox.id) // 7cd11133-96c1-4cc8-9baa-c757b8f8c916
// The sandbox ID can later be used to find the sandbox and start it
const sandbox = await daytona.findOne("7cd11133-96c1-4cc8-9baa-c757b8f8c916");
// Start Sandbox
await sandbox.start();
```
See: [stop (Python SDK)](/docs/python-sdk/sync/sandbox#sandboxstop), [start (Python SDK)](/docs/python-sdk/sync/sandbox#sandboxstart), [find_one (Python SDK)](/docs/python-sdk/sync/daytona#daytonafind_one), [stop (TypeScript SDK)](/docs/typescript-sdk/sandbox#stop), [start (TypeScript SDK)](/docs/typescript-sdk/sandbox#start), [findOne (TypeScript SDK)](/docs/typescript-sdk/daytona#findone)
The stopped state should be used when the Sandbox is expected to be started again soon. Otherwise, it is recommended to stop and then archive the Sandbox to eliminate disk usage costs.
## Archive Sandbox
The Daytona SDK provides methods to archive Sandboxes using Python and TypeScript.
When Sandboxes are archived, the entire filesystem state is moved to very cost-effective object storage, making it possible to keep Sandboxes available for an extended period.
Starting an archived Sandbox takes more time than starting a stopped Sandbox, depending on its size.
A Sandbox must be stopped before it can be archived, and can be started again in the same way as a stopped Sandbox.
```python
# Archive Sandbox
sandbox.archive()
```
```typescript
// Archive Sandbox
await sandbox.archive();
```
See: [archive (Python SDK)](/docs/python-sdk/sync/sandbox#sandboxarchive), [archive (TypeScript SDK)](/docs/typescript-sdk/sandbox#archive)
## Delete Sandbox
The Daytona SDK provides methods to delete Sandboxes using Python and TypeScript.
```python
# Delete Sandbox
sandbox.delete()
```
```typescript
// Delete Sandbox
await sandbox.delete();
```
See: [delete (Python SDK)](/docs/python-sdk/sync/sandbox#sandboxdelete), [delete (TypeScript SDK)](/docs/typescript-sdk/sandbox#delete)
:::tip
Check out the [Daytona CLI](/docs/en/getting-started#setting-up-the-daytona-cli) if you prefer managing Sandboxes through the terminal:
```bash
daytona sandbox list
```
```text
Sandbox State Region Last Event
───────────────────────────────────────────────────────────────────────────
ugliest_quokka STARTED us 1 hour ago
associated_yak STARTED us 14 hours ago
developed_lemur STARTED us 17 hours ago
```
```bash
daytona sandbox start|stop|remove --all
```
```text
All sandboxes have been deleted
```
:::
## Automated Lifecycle Management
Daytona Sandboxes can be automatically stopped, archived, and deleted based on user-defined intervals.
### Auto-stop Interval
The auto-stop interval parameter sets the amount of time after which a running Sandbox will be automatically stopped.
Sandbox activity, such as SDK API calls or network requests through [preview URLs](/docs/en/preview-and-authentication), will reset the auto-stop timer.
The parameter can either be set to:
- a time interval in minutes
- `0`, which disables the auto-stop functionality, allowing the sandbox to run indefinitely
If the parameter is not set, the default interval of `15` minutes will be used.
```python
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
snapshot="my-snapshot-name",
auto_stop_interval=0, # Disables the auto-stop feature - default is 15 minutes
))
```
```typescript
const sandbox = await daytona.create({
snapshot: "my-snapshot-name",
autoStopInterval: 0, // Disables the auto-stop feature - default is 15 minutes
});
```
### Auto-archive Interval
The auto-archive interval parameter sets the amount of time after which a continuously stopped Sandbox will be automatically archived.
The parameter can either be set to:
- a time interval in minutes
- `0`, which means the maximum interval of `30 days` will be used
If the parameter is not set, the default interval of `7 days` days will be used.
```python
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
snapshot="my-snapshot-name",
auto_archive_interval=60 # Auto-archive after a Sandbox has been stopped for 1 hour
))
```
```typescript
const sandbox = await daytona.create({
snapshot: "my-snapshot-name",
autoArchiveInterval: 60 // Auto-archive after a Sandbox has been stopped for 1 hour
});
```
### Auto-delete Interval
The auto-delete interval parameter sets the amount of time after which a continuously stopped Sandbox will be automatically deleted. By default, Sandboxes will never be automatically deleted.
The parameter can either be set to:
- a time interval in minutes
- `-1`, which disables the auto-delete functionality
- `0`, which means the Sandbox will be deleted immediately after stopping
If the parameter is not set, the Sandbox will not be deleted automatically.
```python
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
snapshot="my-snapshot-name",
auto_delete_interval=60, # Auto-delete after a Sandbox has been stopped for 1 hour
))
# Delete the Sandbox immediately after it has been stopped
sandbox.set_auto_delete_interval(0)
# Disable auto-deletion
sandbox.set_auto_delete_interval(-1)
```
```typescript
const sandbox = await daytona.create({
snapshot: "my-snapshot-name",
autoDeleteInterval: 60, // Auto-delete after a Sandbox has been stopped for 1 hour
});
// Delete the Sandbox immediately after it has been stopped
await sandbox.setAutoDeleteInterval(0)
// Disable auto-deletion
await sandbox.setAutoDeleteInterval(-1)
```
## Run Indefinitely
By default, Sandboxes auto-stop after 15 minutes of inactivity. To keep a Sandbox running without interruption, set the auto-stop interval to `0` when creating a new Sandbox:
```python
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
snapshot="my-snapshot-name",
auto_stop_interval=0, # Disables the auto-stop feature - default is 15 minutes
))
```
```typescript
const sandbox = await daytona.create({
snapshot: "my-snapshot-name",
autoStopInterval: 0, // Disables the auto-stop feature - default is 15 minutes
});
```
title: Snapshots
import { TabItem, Tabs } from '@astrojs/starlight/components'
Snapshots are Sandbox templates that can be created from [Docker](https://www.docker.com/) or [OCI](https://opencontainers.org/) compatible images. New Sandboxes can be created from a custom Snapshot pre-configured with your required dependencies, settings, and resources, or from the [default Snapshot](#default-snapshot).
## Creating Snapshots
Snapshots can be created in one of four ways: [from a public image](#using-a-public-image), [from a private image](#using-private-registries), [from a local image](#using-a-local-image), or [using the Declarative Builder](#using-the-declarative-builder).
### Using a Public Image
To create a Snapshot from a public image, follow these steps:
1. Visit the Dashboard and click on [Snapshots](https://app.daytona.io/dashboard/snapshots)
2. Click on **Create Snapshot**
3. Enter the name and tag of any publicly accessible image from Docker Hub (e.g. `alpine:3.21.3`) or from another public container registry (e.g. `my-public-registry.com/custom-alpine:3.21`)
Optionally, set the entrypoint field. If the image does not have a long-running entrypoint, Daytona will automatically run `sleep infinity` to prevent the container from exiting immediately.
:::note
Since images tagged `latest` get frequent updates, only specific tags (e.g. `0.1.0`) are supported. Same idea applies to tags such as `lts` or `stable` and we recommend avoiding those when defining an image.
:::
Once the Snapshot is pulled, validated and has an `Active` state, it is ready to be used.
### Images from Private Registries
To create a Snapshot from an image that is available in a private container registry:
1. Go to the [Registries](https://app.daytona.io/dashboard/registries) page in the Dashboard
2. Click the **Add Registry** button.
3. Fill out the form with an appropriate custom name, URL, username, password, and project (if applicable)
4. Once the Container Registry is created, you may go back to the [Snapshots](https://app.daytona.io/dashboard/snapshots) page
5. When creating the Snapshot, make sure to input the entire private image name, including the registry location and project name (e.g. `my-private-registry.com//custom-alpine:3.21`)
The next step is the same; simply set the `CreateSandboxFromSnapshotParams` field to use the custom Snapshot and no further authentication is needed.
#### Using a Private Docker Hub Image
To use a private Docker Hub image, you'll need to [add a Container Registry](/docs/en/snapshots#images-from-private-registries) with your Docker Hub credentials:
- **Registry URL**: Set this to `docker.io`
- **Username**: Enter your Docker Hub username (the account with access to the private image)
- **Password**: Use a [Docker Hub Personal Access Token](https://docs.docker.com/docker-hub/access-tokens/) (not your account password)
- **Create the Snapshot**: Once the registry is added, you can create a Snapshot using the full image path as the image name: `docker.io//:`
### Using a Local Image
In order to avoid having to manually set up a private container registry and push your image there, the [Daytona CLI](/docs/en/getting-started#setting-up-the-daytona-cli) allows you to create a Snapshot from your local image or from a local Dockerfile and use it in your Sandboxes.
To create a Snapshot from a local image:
1. Run `docker images` to ensure the image and tag you want to use is available
2. Run `daytona snapshot push ` to create a Snapshot and push it to Daytona, e.g.:
```bash
daytona snapshot push custom-alpine:3.21 --name alpine-minimal
```
:::tip
Use the flags `--cpu`, `--memory` and `--disk` to specify the resources you want the underlying Sandboxes to have
For example `daytona snapshot push custom-alpine:3.21 --name alpine-minimal --cpu 2 --memory 4 --disk 8` will create Alpine Sandboxes with 2 vCPU, 4GiB of memory and 8GiB of disk space.
:::
:::note
Daytona expects the local image to be built for AMD64 architecture. Therefore, the `--platform=linux/amd64` flag is required when building the Docker image if your machine is running on a different architecture.
For more information, see the [CLI documentation](/docs/en/tools/cli#daytona-snapshot-push).
:::
Alternatively, to do it through the CLI, use the `--dockerfile` flag under `create` to pass the path to the Dockerfile you want to use and Daytona will build the Snapshot for you. The COPY/ADD commands will be automatically parsed and added to the context - to manually add files to the context you can use the `--context` flag.
```bash
daytona snapshot create data-analysis01 --dockerfile ./Dockerfile
```
```text
Building image from /Users/idagelic/docs/Dockerfile
Step 1/5 : FROM alpine:latest
...
⡿ Waiting for the Snapshot to be validated ...
...
✓ Use 'harbor-transient.internal.daytona.app/daytona/trying-daytona:0.0.1' to create a new sandbox using this Snapshot
```
### Using the Declarative Builder
The declarative builder allows you to define your Snapshots using a code-first approach. See [Declarative Builder](/docs/declarative-builder) for more information.
### Specifying Resources
Snapshots can be customized with specific resource requirements. By default, Daytona Sandboxes come with **1 vCPU**, **1GB RAM**, and **3GiB disk**.
To customize these resources, use the `Resources` class to define exactly what you need:
```python
from daytona import (
Daytona,
CreateSnapshotParams,
Image,
Resources,
)
daytona = Daytona()
# Create a Snapshot with custom resources
daytona.snapshot.create(
CreateSnapshotParams(
name="my-snapshot",
image=Image.debian_slim("3.12"),
# All resource parameters are optional:
resources=Resources(
cpu=2,
memory=4,
disk=8,
),
),
on_logs=print,
)
```
```typescript
import { Daytona, Image } from "@daytonaio/sdk";
const daytona = new Daytona();
// Create a Snapshot with custom resources
await daytona.snapshot.create(
{
name: "my-snapshot",
image: Image.debianSlim("3.13"),
// All resource parameters are optional:
resources: {
cpu: 2,
memory: 4,
disk: 8,
},
},
{ onLogs: console.log }
);
```
Check your available resources and limits in the [dashboard](https://app.daytona.io/dashboard/limits).
## Using Snapshots
To use a Snapshot in your Sandbox, specify the `snapshot` field in the `CreateSandboxFromSnapshotParams` object:
```python
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
snapshot="my-snapshot-name",
))
```
```typescript
const sandbox = await daytona.create({
snapshot: "my-snapshot-name",
})
```
For examples of running code inside a sandbox, see the [Getting Started Guide](/docs/en/getting-started/#run-code-inside-a-sandbox).
## Deleting Snapshots
To delete custom Snapshots:
1. Go to the [Snapshots](https://app.daytona.io/dashboard/snapshots) page
2. Click the three dots at the end of the row for the Snapshot you want to delete
3. Click the `Delete` button that appears
:::tip
To temporarily disable a Snapshot, instead of deleting, you can click `Disable`. This will prevent the Snapshot from being used in any new Sandboxes but will not delete it.
:::
## Running Docker in a Sandbox
Daytona Sandboxes can run Docker containers inside them (**Docker-in-Docker**), enabling you to build, test, and deploy containerized applications. This is particularly useful when your projects have dependencies on external services like databases, message queues, or other microservices.
Agents can seamlessly interact with these services since they run within the same sandbox environment, providing better isolation and security compared to external service dependencies.
### Creating a DinD Snapshot
You can create a Snapshot with Docker support using pre-built Docker-in-Docker images as a base or by manually installing Docker in a custom image.
#### Using Pre-built Images
The following base images are widely used for creating Docker-in-Docker snapshots or can be used as a base for a custom Dockerfile:
- `docker:28.3.3-dind` - Official Docker-in-Docker image (Alpine-based, lightweight)
- `docker:28.3.3-dind-rootless` - Rootless Docker-in-Docker for enhanced security
- `docker:28.3.2-dind-alpine3.22` - Docker-in-Docker image with Alpine 3.22
#### Manual Docker Installation
Alternatively, you can install Docker manually in a custom Dockerfile:
```dockerfile
FROM ubuntu:22.04
# Install Docker using the official install script
RUN curl -fsSL https://get.docker.com | VERSION=28.3.3 sh -
```
### Use Cases
- Run databases (PostgreSQL, Redis, MySQL) and other services
- Build and test containerized applications
- Deploy microservices and their dependencies
- Create isolated development environments with full container orchestration
:::note
Docker-in-Docker Sandboxes require additional resources due to the Docker daemon overhead. Consider allocating at least 2 vCPU and 4GiB of memory for optimal performance.
:::
## Default Snapshot
When a Sandbox is created with no Snapshot specified, Daytona uses a default Snapshot that includes `python`, `node`, their language servers, and several common pip packages:
- `anthropic` (v0.49.0)
- `beautifulsoup4` (v4.13.3)
- `daytona_sdk` (v0.11.1)
- `django` (v5.1.7)
- `flask` (v3.1.0)
- `huggingface` (v0.0.1)
- `instructor` (v1.7.3)
- `keras` (v3.9.0)
- `langchain` (v0.3.20)
- `llama-index` (v0.12.22)
- `matplotlib` (v3.10.1)
- `numpy` (v2.2.3)
- `ollama` (v0.4.7)
- `openai` (v1.65.4)
- `opencv-python` (v4.11.0.86)
- `pandas` (v2.2.3)
- `pillow` (v11.1.0)
- `pydantic-ai` (v0.0.35)
- `requests` (v2.32.3)
- `scikit-learn` (v1.6.1)
- `scipy` (v1.15.2)
- `seaborn` (v0.13.2)
- `SQLAlchemy` (v2.0.38)
- `transformers` (v4.49.0)
title: SSH Access
import { TabItem, Tabs } from '@astrojs/starlight/components'
You can connect to any of your sandboxes via SSH using token-based authentication.
## Creating an SSH Access Token
To connect to a sandbox, you'll need to create an SSH access token first. This token provides secure, time-limited access to your sandbox.
SSH access can be initialized from the dashboard by opening the sandbox’s options menu and selecting `Create SSH Access`.
It can also be initialized programmatically using one of the SDKs listed below.
```python
from daytona import Daytona
daytona = Daytona()
sandbox = daytona.get("sandbox-abc123")
# Create SSH access token
ssh_access = sandbox.create_ssh_access(expires_in_minutes=60)
print(f"SSH Token: {ssh_access.token}")
```
```typescript
import { Daytona } from '@daytonaio/sdk'
const daytona = new Daytona()
const sandbox = await daytona.get('sandbox-abc123')
// Create SSH access token
const sshAccess = await sandbox.createSshAccess(60)
console.log(`SSH Token: ${sshAccess.token}`)
```
## Connection Command
Once you have your token, connect using:
```bash
ssh @ssh.app.daytona.io
```
## Connecting with VSCode
Connecting your local VSCode to a sandbox requires a few simple steps:
1. Make sure that the [Remote Explorer extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-explorer) is installed in your VSCode.
2. Add a new SSH connection
3. When prompted for the SSH connection URL, paste your SSH command from above.
Find out more about the extension [here](https://code.visualstudio.com/docs/remote/ssh).
## Connecting with JetBrains IDEs
Connecting your local JetBrains IDEs to a sandbox requires a few simple steps:
1. Download the [JetBrains Gateway](https://www.jetbrains.com/remote-development/gateway/) app to your local machine.
2. Add a new connection.
3. When prompted for the SSH connection URL, paste your SSH command from above.
4. Choose an IDE you want installed in your sandbox.
## Managing SSH Access
### Token Expiration
SSH access tokens expire automatically for security:
- **Default**: 60 minutes
### Revoking Access
You can revoke SSH access tokens at any time:
```python
# Revoke all SSH access for the sandbox
sandbox.revoke_ssh_access()
# Revoke specific SSH access for the sandbox
sandbox.revoke_ssh_access(token="specific-token")
```
```typescript
// Revoke all SSH access for the sandbox
await sandbox.revokeSshAccess()
// Revoke specific SSH access for the sandbox
await sandbox.revokeSshAccess('specific-token')
```
title: CLI
description: A reference of supported operations using the Daytona CLI.
sidebar:
label: Daytona CLI Reference
The `daytona` command-line tool provides access to Daytona's core features including managing Snapshots and the lifecycle of Daytona Sandboxes. View the installation instructions by clicking [here](/docs/en/getting-started#setting-up-the-daytona-cli).
This reference lists all commands supported by the `daytona` command-line tool complete with a description of their behaviour, and any supported flags.
You can access this documentation on a per-command basis by appending the `--help`/`-h` flag when invoking `daytona`.
## daytona
Daytona CLI
```shell
daytona [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
| `--version` | `-v` | Display the version of Daytona |
## daytona autocomplete
Adds a completion script for your shell environment
```shell
daytona autocomplete [bash|zsh|fish|powershell] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona docs
Opens the Daytona documentation in your default browser.
```shell
daytona docs [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona login
Log in to Daytona
```shell
daytona login [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--api-key` | | API key to use for authentication |
| `--help` | | help for daytona |
## daytona logout
Logout from Daytona
```shell
daytona logout [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona mcp
Manage Daytona MCP Server
```shell
daytona mcp [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona mcp config
Outputs JSON configuration for Daytona MCP Server
```shell
daytona mcp config [AGENT_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona mcp init
Initialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)
```shell
daytona mcp init [AGENT_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona mcp start
Start Daytona MCP Server
```shell
daytona mcp start [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona organization
Manage Daytona organizations
```shell
daytona organization [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona organization create
Create a new organization and set it as active
```shell
daytona organization create [ORGANIZATION_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona organization delete
Delete an organization
```shell
daytona organization delete [ORGANIZATION] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona organization list
List all organizations
```shell
daytona organization list [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--format` | `-f` | Output format. Must be one of (yaml, json) |
| `--help` | | help for daytona |
## daytona organization use
Set active organization
```shell
daytona organization use [ORGANIZATION] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona sandbox
Manage Daytona sandboxes
```shell
daytona sandbox [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona sandbox create
Create a new sandbox
```shell
daytona sandbox create [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--name` | | Name of the sandbox |
| `--auto-archive` | | Auto-archive interval in minutes (0 means the maximum interval will be used) |
| `--auto-delete` | | Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) |
| `--auto-stop` | | Auto-stop interval in minutes (0 means disabled) |
| `--class` | | Sandbox class type (small, medium, large) |
| `--context` | `-c` | Files or directories to include in the build context (can be specified multiple times) |
| `--cpu` | | CPU cores allocated to the sandbox |
| `--disk` | | Disk space allocated to the sandbox in GB |
| `--dockerfile` | `-f` | Path to Dockerfile for Sandbox snapshot |
| `--env` | `-e` | Environment variables (format: KEY=VALUE) |
| `--gpu` | | GPU units allocated to the sandbox |
| `--label` | `-l` | Labels (format: KEY=VALUE) |
| `--memory` | | Memory allocated to the sandbox in MB |
| `--name` | | Name of the sandbox |
| `--network-allow-list` | | Comma-separated list of allowed CIDR network addresses for the sandbox |
| `--network-block-all` | | Whether to block all network access for the sandbox |
| `--public` | | Make sandbox publicly accessible |
| `--snapshot` | | Snapshot to use for the sandbox |
| `--target` | | Target region (eu, us) |
| `--user` | | User associated with the sandbox |
| `--volume` | `-v` | Volumes to mount (format: VOLUME_NAME:MOUNT_PATH) |
| `--help` | | help for daytona |
## daytona sandbox delete
Delete a sandbox
```shell
daytona sandbox delete [SANDBOX_ID] | [SANDBOX_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--all` | `-a` | Delete all sandboxes |
| `--help` | | help for daytona |
## daytona sandbox info
Get sandbox info
```shell
daytona sandbox info [SANDBOX_ID] | [SANDBOX_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--format` | `-f` | Output format. Must be one of (yaml, json) |
| `--help` | | help for daytona |
## daytona sandbox list
List sandboxes
```shell
daytona sandbox list [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--format` | `-f` | Output format. Must be one of (yaml, json) |
| `--limit` | `-l` | Maximum number of items per page |
| `--page` | `-p` | Page number for pagination (starting from 1) |
| `--help` | | help for daytona |
## daytona sandbox start
Start a sandbox
```shell
daytona sandbox start [SANDBOX_ID] | [SANDBOX_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona sandbox stop
Stop a sandbox
```shell
daytona sandbox stop [SANDBOX_ID] | [SANDBOX_NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona snapshot
Manage Daytona snapshots
```shell
daytona snapshot [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona snapshot create
Create a snapshot
```shell
daytona snapshot create [SNAPSHOT] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--context` | `-c` | Files or directories to include in the build context (can be specified multiple times). If not provided, context will be automatically determined from COPY/ADD commands in the Dockerfile |
| `--cpu` | | CPU cores that will be allocated to the underlying sandboxes (default: 1) |
| `--disk` | | Disk space that will be allocated to the underlying sandboxes in GB (default: 3) |
| `--dockerfile` | `-f` | Path to Dockerfile to build |
| `--entrypoint` | `-e` | The entrypoint command for the snapshot |
| `--image` | `-i` | The image name for the snapshot |
| `--memory` | | Memory that will be allocated to the underlying sandboxes in GB (default: 1) |
| `--help` | | help for daytona |
## daytona snapshot delete
Delete a snapshot
```shell
daytona snapshot delete [SNAPSHOT_ID] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--all` | `-a` | Delete all snapshots |
| `--help` | | help for daytona |
## daytona snapshot list
List all snapshots
```shell
daytona snapshot list [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--format` | `-f` | Output format. Must be one of (yaml, json) |
| `--limit` | `-l` | Maximum number of items per page |
| `--page` | `-p` | Page number for pagination (starting from 1) |
| `--help` | | help for daytona |
## daytona snapshot push
Push local snapshot
```shell
daytona snapshot push [SNAPSHOT] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--cpu` | | CPU cores that will be allocated to the underlying sandboxes (default: 1) |
| `--disk` | | Disk space that will be allocated to the underlying sandboxes in GB (default: 3) |
| `--entrypoint` | `-e` | The entrypoint command for the image |
| `--memory` | | Memory that will be allocated to the underlying sandboxes in GB (default: 1) |
| `--name` | `-n` | Specify the Snapshot name |
| `--help` | | help for daytona |
## daytona version
Print the version number
```shell
daytona version [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona volume
Manage Daytona volumes
```shell
daytona volume [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona volume create
Create a volume
```shell
daytona volume create [NAME] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--size` | `-s` | Size of the volume in GB |
| `--help` | | help for daytona |
## daytona volume delete
Delete a volume
```shell
daytona volume delete [VOLUME_ID] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--help` | | help for daytona |
## daytona volume get
Get volume details
```shell
daytona volume get [VOLUME_ID] [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--format` | `-f` | Output format. Must be one of (yaml, json) |
| `--help` | | help for daytona |
## daytona volume list
List all volumes
```shell
daytona volume list [flags]
```
__Flags__
| Long | Short | Description |
| :--- | :---- | :---------- |
| `--format` | `-f` | Output format. Must be one of (yaml, json) |
| `--help` | | help for daytona |
title: Volumes
import { Tabs, TabItem } from '@astrojs/starlight/components';
Volumes are FUSE-based mounts that provide shared file access across Sandboxes. They allow Sandboxes to read from large files instantly - no need to upload files manually to each Sandbox. Volume data is stored on an S3-compatible object store.
- Multiple volumes can be mounted to a single Sandbox
- A single volume can be mounted to multiple Sandboxes
## Creating Volumes
Before mounting a volume to a Sandbox, it must be created.
```bash
volume = daytona.volume.get("my-volume", create=True)
```
```bash
const volume = await daytona.volume.get('my-volume', true)
```
See: [volume.get (Python SDK)](/docs/python-sdk/sync/volume/#volumeserviceget), [volume.get (TypeScript SDK)](/docs/typescript-sdk/volume/#get)
## Mounting Volumes
Once a volume is created, it can be mounted to a Sandbox by specifying it in the `CreateSandboxFromSnapshotParams` object. Volume mount paths must meet the following requirements:
- **Must be absolute paths**: Mount paths must start with `/` (e.g., `/home/daytona/volume`)
- **Cannot be root directory**: Cannot mount to `/` or `//`
- **No relative path components**: Cannot contain `/../`, `/./`, or end with `/..` or `/.`
- **No consecutive slashes**: Cannot contain multiple consecutive slashes like `//` (except at the beginning)
- **Cannot mount to system directories**: The following system directories are prohibited:
- `/proc`, `/sys`, `/dev`, `/boot`, `/etc`, `/bin`, `/sbin`, `/lib`, `/lib64`
```python
import os
from daytona import CreateSandboxFromSnapshotParams, Daytona, VolumeMount
daytona = Daytona()
# Create a new volume or get an existing one
volume = daytona.volume.get("my-volume", create=True)
# Mount the volume to the sandbox
mount_dir_1 = "/home/daytona/volume"
params = CreateSandboxFromSnapshotParams(
language="python",
volumes=[VolumeMount(volumeId=volume.id, mountPath=mount_dir_1)],
)
sandbox = daytona.create(params)
```
```typescript
import { Daytona } from '@daytonaio/sdk'
import path from 'path'
const daytona = new Daytona()
// Create a new volume or get an existing one
const volume = await daytona.volume.get('my-volume', true)
// Mount the volume to the sandbox
const mountDir1 = '/home/daytona/volume'
const sandbox1 = await daytona.create({
language: 'typescript',
volumes: [{ volumeId: volume.id, mountPath: mountDir1 }],
})
```
See: [CreateSandboxFromSnapshotParams (Python SDK)](/docs/python-sdk/sync/daytona#createSandboxBaseParams), [CreateSandboxFromSnapshotParams (TypeScript SDK)](/docs/typescript-sdk/daytona#createSandboxBaseParams)
## Working with Volumes
Once mounted, you can read from and write to the volume just like any other directory in the Sandbox file system. Files written to the volume persist beyond the lifecycle of any individual Sandbox.
```python
# Write to a file in the mounted volume
with open("/home/daytona/volume/example.txt", "w") as f:
f.write("Hello from Daytona volume!")
# When you're done with the sandbox, you can remove it
# The volume will persist even after the sandbox is removed
sandbox.delete()
```
```typescript
import fs from 'fs/promises'
// Write to a file in the mounted volume
await fs.writeFile('/home/daytona/volume/example.txt', 'Hello from Daytona volume!')
// When you're done with the sandbox, you can remove it
// The volume will persist even after the sandbox is removed
await daytona.delete(sandbox1)
```
## Deleting Volumes
When a volume is no longer needed, it can be deleted.
```python
volume = daytona.volume.get("my-volume", create=True)
daytona.volume.delete(volume)
```
```typescript
const volume = await daytona.volume.get('my-volume', true)
await daytona.volume.delete(volume)
```
## Limitations
Since volumes are FUSE-based mounts, they can not be used for applications that require block storage access (like database tables).
Volumes are generally slower for both read and write operations compared to the local Sandbox file system.
title: Web Terminal
import { TabItem, Tabs } from '@astrojs/starlight/components'
Daytona provides a Web Terminal for interacting with your Sandboxes, allowing for a convenient way to view files, run commands, and debug.
You can open it by clicking on the Terminal icon `>_` in the [Sandbox list](https://app.daytona.io/dashboard/sandboxes) under Access for any running Sandbox. It is available by default and is accessible on port `22222`.
```text
ID State Region Created Access
──────────────────────────────────────────────────────────────────────────────
sandbox-963e3f71 STARTED us 12 minutes ago >_
```
:::note
Since Terminal access is a very sensitive procedure, it is accessible only to users in your Organization, even when setting the `public` parameter to `True` in `CreateSandboxFromSnapshotParams` or `CreateSandboxFromImageParams`.
:::
title: Webhooks
description: Connect your applications to Daytona events in real-time with webhooks for automation, monitoring, and integrations.
import { TabItem, Tabs } from '@astrojs/starlight/components'
Webhooks are HTTP callbacks that Daytona sends to your specified endpoints when specific events occur.
Think of them as "reverse API calls" - instead of your application asking Daytona for updates, Daytona
proactively notifies your application when something important happens.
## Use Cases
Webhooks enable powerful automation and integration scenarios:
- **Real-time Notifications**: Get instant alerts when sandboxes are created, started, or stopped
- **Automated Workflows**: Trigger deployment pipelines when snapshots are created
- **Monitoring & Analytics**: Track usage patterns and resource utilization across your organization
- **Integration**: Connect Daytona with your existing tools like Slack, Discord, or custom applications
- **Audit & Compliance**: Maintain detailed logs of all important changes
## Getting Started
### Accessing Webhooks
If you don't see **Webhooks** in your dashboard sidebar, contact [support@daytona.io](mailto:support@daytona.io) to enable webhooks for your organization. Provide your organization ID (found in your organization settings) when requesting access.
Once webhooks are enabled for your organization:
1. Navigate to your [Daytona Dashboard](https://app.daytona.io/dashboard)
2. Click **Webhooks** in the left sidebar
3. You'll be able to access the webhook management interface
:::note
Webhooks are available to organization admins and members with appropriate permissions.
:::
## Managing Webhook Endpoints
### Creating Endpoints
To start receiving webhook events:
1. Go to the **Endpoints** tab in your webhook dashboard
2. Click **Add Endpoint**
3. Configure your endpoint:
- **Endpoint URL**: The HTTPS endpoint where you want to receive events
- **Description**: A helpful description for this endpoint
- **Subscribe to events**: Select which events you want to receive
### Testing Endpoints
Before going live, test your webhook endpoints:
1. Select webhook from **Endpoints** list
2. Go to the **Testing** tab
3. Configure test event and send it
4. Verify your endpoint receives the test payload correctly
5. Check that your application handles the webhook format properly
## Available Events
Daytona sends webhooks for lifecycle events across your infrastructure resources. You can subscribe to specific event types or receive all events and filter them in your application.
##### Event Categories
- Sandbox Lifecycle Events
- Snapshot Lifecycle Events
- Volume Lifecycle Events
## Webhook Payload Format
All webhook events follow a consistent structure:
```json
{
"event": "event.type",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
// Event-specific data
}
}
```
**Common Fields:**
- `event`: The type of event (e.g., "sandbox.created")
- `timestamp`: ISO 8601 timestamp when the event occurred
- `data`: Event-specific payload containing relevant information
## Monitoring and Activity
### Activity
The **Activity** tab provides a visual overview of your webhook activity, including delivery statistics, event volume trends, and performance metrics to help you monitor the health of your webhook integrations.
### Event Logs
The **Logs** tab shows detailed information about webhook deliveries, including event history, delivery status, and retry information for troubleshooting and monitoring purposes.