# Bring Your Own Compute (BYOC)

Bring Your Own Compute (BYOC) enables you to use your own runner machines to run sandbox workloads. Runners are machines that power Daytona's compute plane and provide the underlying infrastructure. Each runner is responsible for:

- **Workload execution**: running sandbox workloads
- **Resource management**: allocating and monitoring CPU, memory, and disk resources
- **Health reporting**: providing metrics and health status to the Daytona control plane
- **Network connectivity**: managing sandbox networking, proxy connections, and SSH access

Runners in [shared](https://www.daytona.io/docs/en/regions.md#shared-regions) and [dedicated](https://www.daytona.io/docs/en/regions.md#dedicated-regions) regions are fully managed by Daytona — from provisioning and maintenance to monitoring and scaling. For custom regions, you bring your own runner machines and are responsible for their management and operation.

Daytona provides two sets of runner management endpoints: [custom runners](#custom-runners) (`/runners`) and [admin operations](#admin-operations) (`/admin/runners`). While both support creating, listing, updating, and deleting runners, they serve different purposes and offer different levels of control.

Custom runner endpoints are scoped to your [organization](https://www.daytona.io/docs/en/organizations.md) and support the `X-Daytona-Organization-ID` header. Admin endpoints operate across the entire platform and do not require an organization header.

Both `Runner` and `RunnerFull` share the same base fields, including resource metrics, allocated resources, availability score, snapshot count, and started sandboxes. The `RunnerFull` type extends `Runner` with the runner's `apiKey` and `regionType` fields.

## Custom regions

Custom regions are created and managed by your organization, allowing you to use your own runner machines and scale compute resources independently within each region. This provides maximum control over data locality, compliance, and infrastructure configuration.

Additionally, custom regions have no limits applied for concurrent resource usage, giving you full control over capacity and performance.

### Custom region configuration

**name** (required)

- A unique identifier for your region
- Must contain only letters, numbers, underscores, periods, and hyphens
- Used for targeting this region when creating a sandbox

**proxyUrl** (optional)

- The URL of the proxy service that routes traffic to sandboxes in this region
- Required if the runner machines in this region are deployed in a private network

**sshGatewayUrl** (optional)

- The URL of the SSH gateway that handles SSH connections to sandboxes in this region
- Required if the runner machines in this region are deployed in a private network

**snapshotManagerUrl** (optional)

- The URL of the snapshot manager that handles storage and retrieval of snapshots in this region
- Required if the runner machines in this region are deployed in a private network

### Create a custom region

Daytona provides methods to create a custom region using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/POST/regions).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions)
2. Click the **Create Region** button
3. Enter the **region name**, **proxy URL**, **SSH gateway URL**, and **snapshot manager URL**

- **Region name**: the name of the region; must contain only letters, numbers, underscores, periods, and hyphens.
- **Proxy URL** (optional): the URL of the custom proxy for this region
- **SSH gateway URL** (optional): the URL of the custom SSH gateway for this region
- **Snapshot manager URL** (optional): the URL of the custom snapshot manager for this region

4. Click **Create** to create the region


```bash
curl https://app.daytona.io/api/regions \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-custom-region",
    "proxyUrl": "https://proxy.example.com",
    "sshGatewayUrl": "ssh://ssh-gateway.example.com",
    "snapshotManagerUrl": "https://snapshot-manager.example.com"
  }'
```


The response includes the region ID and credentials for any optional services you configured:

```json
{
  "id": "region_12345",
  "proxyApiKey": "proxy-api-key-xyz",
  "sshGatewayApiKey": "ssh-gateway-api-key-abc",
  "snapshotManagerUsername": "daytona",
  "snapshotManagerPassword": "generated-password"
}
```

For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**createRegion (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/POST/regions)

### Custom region credentials

When you create a custom region, Daytona will provide credentials for any optional services you configure:

- An API key that should be used by your proxy service to authenticate with Daytona
- An API key that should be used by your SSH gateway service to authenticate with Daytona
- Basic authentication credentials that Daytona uses to access your snapshot manager service

:::note
If needed, these credentials can always be regenerated, but you will need to redeploy the corresponding services with the updated credentials.
:::

### List custom regions

Daytona provides methods to list all available regions for your organization using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/GET/regions).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions)
2. The list of regions is displayed in the **Regions** table with the following columns:

- **Name**: the name of the region
- **ID**: the ID of the region
- **Created**: the date and time the region was created


```bash
curl https://app.daytona.io/api/regions \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**listAvailableRegions (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/GET/regions)

### Get a custom region

Daytona provides methods to get the details of a specific region using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/GET/regions/{id}).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions)
2. Click the region you want to get the details of
3. The region details are displayed in the **Region Details** panel with the following information:

- **Name**: the name of the region
- **ID**: the ID of the region
- **Created**: the date and time the region was created
- **URLs**: the URLs of the region's proxy, SSH gateway, and snapshot manager services


```bash
curl https://app.daytona.io/api/regions/{regionId} \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**getRegionById (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/GET/regions/{id})

### Update a custom region

Daytona provides methods to update the configuration of an existing custom region using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/PATCH/regions/{id}).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions)
2. Click the region you want to update the configuration of
3. Click the three dots menu (**⋮**) next to the region and select the **Edit** icon
4. Enter the new **proxy URL**, **SSH gateway URL**, and **snapshot manager URL**
5. Click **Update** to update the region configuration

- **Proxy URL** (optional): the new URL of the custom proxy for this region
- **SSH gateway URL** (optional): the new URL of the custom SSH gateway for this region
- **Snapshot manager URL** (optional): the new URL of the custom snapshot manager for this region


```bash
curl https://app.daytona.io/api/regions/{regionId} \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "proxyUrl": "https://new-proxy.example.com",
    "sshGatewayUrl": "ssh://new-ssh-gateway.example.com",
    "snapshotManagerUrl": "https://new-snapshot-manager.example.com"
  }'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**updateRegion (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/PATCH/regions/{id})

### Delete a custom region

Daytona provides methods to delete a custom region using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/DELETE/regions/{id}). Regions that have runners assigned to them cannot be deleted.

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/regions)
2. Click the region you want to delete
3. Click the three dots menu (**⋮**) next to the region and select **Delete**
4. Confirm the deletion


```bash
curl https://app.daytona.io/api/regions/{regionId} \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**deleteRegion (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/DELETE/regions/{id})

#### Regenerate proxy API key

Daytona provides an API to regenerate the proxy API key for a custom region.


```bash
curl https://app.daytona.io/api/regions/{regionId}/regenerate-proxy-api-key \
  --request POST \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**regenerateProxyApiKey (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/POST/regions/{id}/regenerate-proxy-api-key)

#### Regenerate SSH gateway API key

Daytona provides an API to regenerate the SSH gateway API key for a custom region.


```bash
curl https://app.daytona.io/api/regions/{regionId}/regenerate-ssh-gateway-api-key \
  --request POST \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**regenerateSshGatewayApiKey (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/POST/regions/{id}/regenerate-ssh-gateway-api-key)

#### Regenerate snapshot manager credentials

Daytona provides an API to regenerate the snapshot manager credentials for a custom region.


```bash
curl https://app.daytona.io/api/regions/{regionId}/regenerate-snapshot-manager-credentials \
  --request POST \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations) reference:

> [**regenerateSnapshotManagerCredentials (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/organizations/POST/regions/{id}/regenerate-snapshot-manager-credentials)

## Custom runners

Custom runners are created and managed by your organization, allowing you to use your own runner machines and scale compute resources independently within each custom region.

### Custom runner configuration

**name** (required)

- A unique identifier for the runner
- Must contain only letters, numbers, underscores, periods, and hyphens
- Helps distinguish between multiple runners in the same region

**regionId** (required)

- The ID of the region this runner is assigned to
- Must be a custom region owned by your organization
- All runners in a region share the region's proxy and SSH gateway configuration

### Create a custom runner

Daytona provides methods to create a custom runner using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/POST/runners).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners)
2. Click the **Create Runner** button
3. Select a **region** and enter its **name**
4. Click **Create** to create the runner

- **Region**: the region this runner is assigned to
- **Name**: the name of the runner


```bash
curl https://app.daytona.io/api/runners \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-custom-runner",
    "regionId": "region_12345"
  }'
```


Upon creating a runner, you will be presented with a secure token that you can use to authenticate the runner with the Daytona control plane. The response includes the runner ID and the API key token:

```json
{
  "id": "runner123",
  "apiKey": "dtn_1234567890"
}
```

:::note
Save this token securely. You won't be able to see it again.
:::

For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners) reference:

> [**createRunner (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/POST/runners)

### List custom runners

Daytona provides methods to list all runners in your organization using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/GET/runners).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners)
2. The list of runners is displayed in the **Runners** table with the following columns:

- **ID**: the ID of the runner
- **Name**: the name of the runner
- **Region**: the region this runner is assigned to
- **State**: the state of the runner
- **Schedulable**: checkbox to mark the runner as unschedulable


```bash
curl https://app.daytona.io/api/runners \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners) reference:

> [**listRunners (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/GET/runners)

### Get a custom runner

Daytona provides methods to get the details of a specific runner using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/GET/runners/{id}).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners)
2. Click the runner you want to get the details of
3. The runner details are displayed in the **Runner Details** panel with the following information:

- **Name**: the name of the runner
- **UUID**: the UUID of the runner
- **State**: the state of the runner
- **Schedulable**: whether the runner is schedulable
- **Region**: the region this runner is assigned to
- **Version**: the version of the runner
- **Health metrics**: the health metrics of the runner (availability score, CPU, memory, disk usage)
- **Active sandboxes**: the number of active sandboxes running on the runner
- **Snapshots**: the number of snapshots stored on the runner
- **Total resources**: the total resources allocated to the runner (CPU, memory, disk)
- **Created at**: the date and time the runner was created
- **Updated at**: the date and time the runner was last updated


```bash
curl https://app.daytona.io/api/runners/{runnerId} \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners) reference:

> [**getRunnerById (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/GET/runners/{id})

### Update runner scheduling

Daytona provides methods to update the scheduling status of a runner using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/PATCH/runners/{id}/scheduling). This allows you to mark a runner as unschedulable, preventing new sandboxes from being assigned to it.

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners)
2. Use the checkbox to mark the runner as unschedulable or schedulable


```bash
curl https://app.daytona.io/api/runners/{runnerId}/scheduling \
  --request PATCH \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners) reference:

> [**updateRunnerScheduling (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/PATCH/runners/{id}/scheduling)

### Delete a custom runner

Daytona provides methods to delete a custom runner using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners) or programmatically using the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/DELETE/runners/{id}).

1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/runners)
2. Click the three dots menu (**⋮**) next to the runner you want to delete and select **Delete**
3. Confirm the deletion


```bash
curl https://app.daytona.io/api/runners/{runnerId} \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners) reference:

> [**deleteRunner (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/runners/DELETE/runners/{id})

## Admin operations

Admin runners operate across the entire platform. They do not require the `X-Daytona-Organization-ID` header and return `RunnerFull` objects with additional `apiKey` and `regionType` fields.

### Admin runner configuration

**name** (required)

- A unique identifier for the runner
- Must contain only letters, numbers, underscores, periods, and hyphens

**regionId** (required)

- The ID of the region this runner is assigned to

**apiKey** (required)

- The API key used to authenticate the runner with the Daytona control plane

**apiVersion** (required)

- The API version of the runner
- Must be `0` or `2`

**domain** (optional)

- The domain of the runner

**apiUrl** (optional)

- The API URL of the runner

**proxyUrl** (optional)

- The proxy URL of the runner

**cpu** (optional)

- The CPU capacity of the runner

**memoryGiB** (optional)

- The memory capacity of the runner in GiB

**diskGiB** (optional)

- The disk capacity of the runner in GiB

### Create a runner

Daytona provides an admin API to create a runner with full configuration, including resource capacity and network settings. Unlike the custom runner endpoint, you must provide your own `apiKey` and specify the `apiVersion` (`0` or `2`).


```bash
curl https://app.daytona.io/api/admin/runners \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-custom-runner",
    "regionId": "region_12345",
    "apiKey": "dtn_1234567890",
    "apiVersion": "2",
    "domain": "runner1.example.com",
    "apiUrl": "https://api.runner1.example.com",
    "proxyUrl": "https://proxy.runner1.example.com",
    "cpu": 8,
    "memoryGiB": 16,
    "diskGiB": 100
  }'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin) reference:

> [**adminCreateRunner (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin/POST/admin/runners)

### List runners

Daytona provides an admin API to list all runners with full details, including resource usage metrics. You can optionally filter runners by region.


```bash
# List all runners
curl https://app.daytona.io/api/admin/runners \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'

# Filter runners by region
curl 'https://app.daytona.io/api/admin/runners?regionId=region_12345' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin) reference:

> [**adminListRunners (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin/GET/admin/runners)

### Get runner

Daytona provides an admin API to get full runner details, including resource usage and allocation metrics.


```bash
curl https://app.daytona.io/api/admin/runners/{runnerId} \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin) reference:

> [**adminGetRunnerById (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin/GET/admin/runners/{id})

### Update runner scheduling

Daytona provides an admin API to update the scheduling status of a runner.


```bash
curl https://app.daytona.io/api/admin/runners/{runnerId}/scheduling \
  --request PATCH \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin) reference:

> [**adminUpdateRunnerScheduling (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin/PATCH/admin/runners/{id}/scheduling)

### Delete runner

Daytona provides an admin API to delete a runner.


```bash
curl https://app.daytona.io/api/admin/runners/{runnerId} \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```


For more information, see the [API](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin) reference:

> [**adminDeleteRunner (API)**](https://www.daytona.io/docs/en/tools/api.md#daytona/tag/admin/DELETE/admin/runners/{id})

## Runner deployment

After registering a custom runner and obtaining its secure token, install and configure the Daytona runner application on your infrastructure. Daytona provides official [Terraform modules](#terraform) and [Helm charts](#helm-charts) for automated runner deployment.

### Terraform

Daytona provides a Terraform module for deploying runners on AWS EC2 with automated installation and configuration. The module handles instance provisioning, security configuration, and runner registration with the Daytona platform.

View the full documentation and examples in the GitHub repository:

- **GitHub**: [daytonaio/terraform-modules](https://github.com/daytonaio/terraform-modules)

#### Prerequisites

- Terraform >= 1.0
- AWS credentials configured
- VPC and subnet already created
- Ubuntu 22.04 or later AMI
- Daytona runner .deb package hosted at an accessible URL

#### Basic example

```hcl
module "daytona_runner" {
  source = "./runner"

  # Network Configuration
  vpc_id    = "vpc-1234567890abcdef0"
  subnet_id = "subnet-1234567890abcdef0"

  # EC2 Configuration
  ami_id        = "ami-0c55b159cbfafe1f0"  # Ubuntu 22.04 LTS
  instance_type = "t3.medium"

  # Daytona Configuration
  api_url   = "https://daytona.example.com/api"
  api_key   = "your-api-key-here"
  region_id = "your-region-id"

  # Optional: Enable SSM for secure access
  enable_ssm = true

  tags = {
    Environment = "production"
    ManagedBy   = "terraform"
  }
}
```

#### Advanced example

```hcl
module "daytona_runner" {
  source = "./runner"

  name_prefix = "production"

  # Network Configuration
  vpc_id    = "vpc-1234567890abcdef0"
  subnet_id = "subnet-1234567890abcdef0"

  # EC2 Configuration
  ami_id             = "ami-0c55b159cbfafe1f0"
  instance_type      = "t3.large"
  root_volume_size   = 100
  root_volume_type   = "gp3"

  # Daytona Configuration
  api_url   = "https://api.daytona.example.com"
  api_key   = var.api_key  # Use variable for sensitive data
  region_id = var.region_id

  # Security Configuration
  enable_ssh       = true
  ssh_cidr_blocks  = ["10.0.0.0/8"]
  key_name         = "my-ssh-key"
  enable_ssm       = true

  tags = {
    Environment = "production"
    Team        = "platform"
    ManagedBy   = "terraform"
  }
}
```

#### Inputs

| **Name**                            | **Description**                                | **Type**     | **Default**   | **Required** |
| ----------------------------------- | ---------------------------------------------- | ------------ | ------------- | ------------ |
| **`vpc_id`**                        | VPC ID where the runner will be deployed       | string       | -             | yes          |
| **`subnet_id`**                     | Subnet ID where the runner will be deployed    | string       | -             | yes          |
| **`ami_id`**                        | AMI ID for the EC2 instance                    | string       | -             | yes          |
| **`api_url`**                       | Daytona API URL                                | string       | -             | yes          |
| **`api_key`**                       | Daytona API key                                | string       | -             | yes          |
| **`region_id`**                     | Daytona region ID                              | string       | -             | yes          |
| **`name_prefix`**                   | Prefix for resource names                      | string       | "daytona"     | no           |
| **`runner_name`**                   | Name for the runner (used in API registration) | string       | null          | no           |
| **`runner_version`**                | Daytona runner version                         | string       | "0.125.0-rc1" | no           |
| **`instance_type`**                 | EC2 instance type                              | string       | "t3.medium"   | no           |
| **`key_name`**                      | SSH key pair name                              | string       | null          | no           |
| **`root_volume_type`**              | Root volume type                               | string       | "gp3"         | no           |
| **`root_volume_size`**              | Root volume size in GB                         | number       | 50            | no           |
| **`poll_timeout`**                  | Job polling timeout                            | string       | "30s"         | no           |
| **`poll_limit`**                    | Job polling limit                              | number       | 10            | no           |
| **`enable_ssh`**                    | Enable SSH access                              | bool         | false         | no           |
| **`ssh_cidr_blocks`**               | CIDR blocks for SSH access                     | list(string) | []            | no           |
| **`enable_ssm`**                    | Enable SSM Session Manager                     | bool         | true          | no           |
| **`additional_security_group_ids`** | Additional security group IDs to attach        | list(string) | []            | no           |
| **`ingress_security_group_ids`**    | Security group IDs allowed to access port 8080 | map(string)  | {}            | no           |
| **`additional_iam_policy_arns`**    | Additional IAM policy ARNs to attach           | list(string) | []            | no           |
| **`custom_iam_policy`**             | Custom IAM policy document (JSON)              | string       | null          | no           |
| **`user_data_append`**              | Additional user data script to run after init  | string       | null          | no           |
| **`tags`**                          | Additional tags                                | map(string)  | {}            | no           |

#### Outputs

| Name                | Description                        |
| ------------------- | ---------------------------------- |
| runner_id           | Daytona runner ID                  |
| runner_name         | Daytona runner name                |
| instance_id         | ID of the EC2 instance             |
| instance_private_ip | Private IP address of the instance |
| instance_public_ip  | Public IP address of the instance  |
| security_group_id   | ID of the security group           |
| iam_role_arn        | ARN of the IAM role                |
| iam_role_name       | Name of the IAM role               |

#### Security considerations

1. **API Key**: The `api_key` is marked as sensitive. Use Terraform variables or a secrets manager.
2. **SSH Access**: Disabled by default. Use SSM Session Manager instead for better security.
3. **Encryption**: Root volume is encrypted by default.
4. **IMDSv2**: Instance Metadata Service v2 is enforced.
5. **Network**: The instance only allows outbound traffic by default.

#### Access using SSM Session Manager

```bash
# No SSH key required
aws ssm start-session --target <instance-id>

# Check runner status
sudo systemctl status daytona-runner

# View logs
sudo journalctl -u daytona-runner -f
```

#### Access using SSH

```bash
ssh -i ~/.ssh/your-key.pem ubuntu@<instance-ip>
```

#### Troubleshooting

Troubleshoot cloud-init issues:

```bash
# View cloud-init output
sudo cat /var/log/cloud-init-output.log

# Check cloud-init status
sudo cloud-init status
```

Troubleshoot runner issues:

```bash
# Service status
sudo systemctl status daytona-runner

# Service logs
sudo journalctl -u daytona-runner -n 100 --no-pager

# Check configuration
sudo cat /etc/daytona/runner.env
```

Verify runner installation:

```bash
# Check if binary exists
ls -la /opt/daytona/runner

# Check binary permissions
file /opt/daytona/runner
```

### Helm charts

Daytona provides a Helm chart for deploying custom regions and their supporting infrastructure on Kubernetes. The `daytona-region` chart deploys a proxy service, optional snapshot manager, and a registration job, allowing you to run Daytona sandboxes within your own Kubernetes cluster.

View the full documentation and examples in the GitHub repository:

- **GitHub**: [daytonaio/helm-charts](https://github.com/daytonaio/helm-charts)

#### Prerequisites

- **Supported OS Architecture:** AMD64/x86_64
- **Docker:** The script will install Docker if not present.
- **Systemd:** Required for service management.

#### Installation

1. Run the runner install script

```bash
curl -sSL https://download.daytona.io/install.sh | sudo bash
```

The script will prompt you for:

- Daytona API URL
- Daytona Admin API Key
- System resource allocation (CPU, memory, disk)
- Domain name for the runner
- Runner API URL
- Optional proxy URL, region, runner capacity, and runner API key

2. Automatic steps performed by the script

- Checks system architecture
- Downloads the Daytona runner binary
- Installs Docker if missing
- Registers the runner with the Daytona API
- Creates and enables a systemd service for the runner
- Starts the runner service

#### Manage the runner service

Check status:

```bash
sudo systemctl status daytona-runner
```

View logs:

```bash
sudo tail -f /var/log/daytona-runner.log
```

Stop service:

```bash
sudo systemctl stop daytona-runner
```

#### Override with environment variables

The following environment variables can be set to override the default values in the install script:

:::tip
Set these variables before running the install script to customize the runner configuration.
:::

| **Variable name**           | **Description**              | **Default value / notes**                     |
| --------------------------- | ---------------------------- | --------------------------------------------- |
| **`CONTAINER_RUNTIME`**     | Container runtime to use     | `sysbox-runc`                                 |
| **`API_TOKEN`**             | API token for runner         | Auto-generated or user-provided               |
| **`TLS_CERT_FILE`**         | Path to TLS certificate file | `/etc/letsencrypt/live/$DOMAIN/fullchain.pem` |
| **`TLS_KEY_FILE`**          | Path to TLS key file         | `/etc/letsencrypt/live/$DOMAIN/privkey.pem`   |
| **`ENABLE_TLS`**            | Enable TLS for runner        | `false`                                       |
| **`API_PORT`**              | Port for runner API          | `3000`                                        |
| **`LOG_FILE_PATH`**         | Path to runner log file      | `/var/log/daytona-runner.log`                 |
| **`LOG_LEVEL`**             | Log level                    | `info`                                        |
| **`AWS_ENDPOINT_URL`**      | AWS S3 endpoint URL          | `https://s3.us-east-1.amazonaws.com`          |
| **`AWS_ACCESS_KEY_ID`**     | AWS access key ID            | (empty)                                       |
| **`AWS_SECRET_ACCESS_KEY`** | AWS secret access key        | (empty)                                       |
| **`AWS_REGION`**            | AWS region                   | `us-east-1`                                   |
| **`AWS_DEFAULT_BUCKET`**    | AWS S3 bucket name           | `daytona`                                     |
| **`SSH_GATEWAY_ENABLE`**    | Enable SSH gateway           | `true` or `false` (auto-detected)             |
| **`SSH_PUBLIC_KEY`**        | SSH gateway public key       | Fetched from API                              |
| **`SSH_HOST_KEY_PATH`**     | Path to SSH host key         | `/etc/ssh/ssh_host_rsa_key`                   |
| **`SERVER_URL`**            | Daytona API URL              | User-provided                                 |