---
title: Snapshots
description: Pre-configured sandbox templates you can use to create sandboxes.
---

import { TabItem, Tabs } from '@astrojs/starlight/components'
import Label from '@components/Label.astro'

Snapshots are sandbox templates created from [Docker](https://www.docker.com/) or [OCI](https://opencontainers.org/) compatible images. Sandboxes can use a [default snapshot](#default-snapshots) or custom snapshots to provide a consistent and reproducible sandbox environments for your dependencies, settings, and resources.

Daytona supports running [Docker](#run-docker-in-a-sandbox) and [Kubernetes](#run-kubernetes-in-a-sandbox) workloads inside sandboxes using snapshots.

## Snapshot lifecycle

A snapshot can have several different states. Each state reflects the current status of your snapshot.

- **Pending**: the snapshot creation has been requested
- **Building**: the snapshot is being built
- **Pulling**: the snapshot image is being pulled from a registry
- **Active**: the snapshot is ready to use for creating sandboxes
- **Inactive**: the snapshot is deactivated
- **Error**: the snapshot creation failed
- **Build Failed**: the snapshot build process failed
- **Removing**: the snapshot is being deleted

:::note
Inactive snapshots cannot be used to create sandboxes. They must be explicitly [re-activated](#activate-snapshots) before use. When activated, the snapshot returns to `pending` state and is re-processed before becoming `active` again.
:::

## Create Snapshots

Daytona provides methods to create snapshots using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/snapshots) or programmatically using the Daytona [Python](/docs/en/python-sdk/sync/snapshot), [TypeScript](/docs/en/typescript-sdk/snapshot), [Ruby](/docs/en/ruby-sdk/snapshot), [Go](/docs/en/go-sdk/daytona#SnapshotService), [Java](/docs/en/java-sdk/snapshot) **SDKs**, [CLI](/docs/en/tools/cli#daytona-snapshot), or [API](/docs/en/tools/api#daytona/tag/snapshots).

Snapshots can be created using:

- [public images](#using-public-images)
- [local images](#using-local-images)
- [images from private registries](#using-images-from-private-registries)
- [the declarative builder](#using-the-declarative-builder)
- [GPU snapshots](#gpu-snapshots) (for [GPU sandboxes](/docs/en/sandboxes#gpu-sandboxes))

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
2. Click the **Create Snapshot** button
3. Enter the **snapshot name**, **image** (tag or digest), **entrypoint**, and **resources**

- **Snapshot name**: Identifier used to reference the snapshot in the SDK or CLI.
- **Image**: Base image for the snapshot. Must include either a tag or a digest (e.g., **`ubuntu:22.04`**). The **`latest`** tag is not allowed. Since images tagged `latest` get frequent updates, only specific tags are supported. Same applies to tags such as `lts` or `stable`, and we recommend avoiding those when defining an image to prevent unexpected behavior.
- **Entrypoint** (optional): The entrypoint command for the snapshot. Ensure that the entrypoint is a long-running command. If not provided, or if the snapshot does not have an entrypoint, `sleep infinity` will be used as the default.
- [**Resources**](/docs/en/sandboxes#resources) (optional): The resources you want the underlying Sandboxes to have. By default, Daytona Sandboxes use **1 vCPU**, **1GiB memory**, and **3GiB storage**.
- **GPU** (optional): Enable the **GPU** option to create a GPU snapshot for [GPU sandboxes](/docs/en/sandboxes#gpu-sandboxes).

<Tabs>
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona, CreateSnapshotParams

daytona = Daytona()
snapshot = daytona.snapshot.create(
    CreateSnapshotParams(name="my-awesome-snapshot", image="python:3.12"),
)
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from "@daytona/sdk";

const daytona = new Daytona();
const snapshot = await daytona.snapshot.create({
  name: "my-awesome-snapshot",
  image: "python:3.12",
});
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
require 'daytona'

daytona = Daytona::Daytona.new
snapshot = daytona.snapshot.create(
  Daytona::CreateSnapshotParams.new(name: 'my-awesome-snapshot', image: 'python:3.12')
)
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
package main

import (
	"context"

	"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
	client, _ := daytona.NewClient()
	ctx := context.Background()
	snapshot, logCh, _ := client.Snapshot.Create(ctx, &types.CreateSnapshotParams{
		Name:  "my-awesome-snapshot",
		Image: "python:3.12",
	})
	for range logCh {
	}
	_ = snapshot
}
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
import io.daytona.sdk.Daytona;
import io.daytona.sdk.model.Snapshot;

final class CreateSnapshot {
    public static void main(String[] args) {
        try (Daytona daytona = new Daytona()) {
            Snapshot snapshot = daytona.snapshot().create("my-awesome-snapshot", "python:3.12");
        }
    }
}
```

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
daytona snapshot create my-awesome-snapshot --image python:3.11-slim --cpu 2 --memory 4
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-awesome-snapshot",
    "imageName": "python:3.11-slim",
    "cpu": 2,
    "memory": 4
  }'
```

</TabItem>
</Tabs>

### Using public images

Daytona supports creating snapshots from any publicly accessible image or container registry.

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
2. Click the **Create Snapshot** button
3. Enter the **snapshot name** and **image** (tag or digest) of any publicly accessible image or container registry

Once the snapshot is pulled, validated, and has an `Active` state, it is ready to be used.

<Tabs>
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona, CreateSnapshotParams

daytona = Daytona()
daytona.snapshot.create(
    CreateSnapshotParams(name="my-awesome-snapshot", image="python:3.11-slim"),
    on_logs=lambda chunk: print(chunk, end=""),
)
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from "@daytona/sdk";

const daytona = new Daytona();
await daytona.snapshot.create(
  { name: "my-awesome-snapshot", image: "python:3.11-slim" },
  { onLogs: console.log },
);
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
require 'daytona'

daytona = Daytona::Daytona.new
params = Daytona::CreateSnapshotParams.new(
  name: 'my-awesome-snapshot',
  image: 'python:3.11-slim'
)
snapshot = daytona.snapshot.create(params) do |chunk|
  print chunk
end
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
package main

import (
	"context"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
	client, _ := daytona.NewClient()
	ctx := context.Background()
	snapshot, logChan, _ := client.Snapshot.Create(ctx, &types.CreateSnapshotParams{
		Name:  "my-awesome-snapshot",
		Image: "python:3.11-slim",
	})
	_ = snapshot
	for range logChan {
	}
}
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
import io.daytona.sdk.Daytona;
import io.daytona.sdk.model.Snapshot;

public class App {
    public static void main(String[] args) {
        try (Daytona daytona = new Daytona()) {
            Snapshot snapshot = daytona.snapshot().create("my-awesome-snapshot", "python:3.11-slim");
        }
    }
}
```

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
daytona snapshot create my-awesome-snapshot --image python:3.11-slim
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-awesome-snapshot",
    "imageName": "python:3.11-slim"
  }'
```

</TabItem>
</Tabs>

### Using local images

Daytona supports creating snapshots from local images or from local Dockerfiles. To create a snapshot from a local image or from a local Dockerfile, use the [Daytona CLI](/docs/en/tools/cli#daytona-snapshot).

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.

1. Ensure the image and tag you want to use is available

```bash
docker images
```

2. Create a snapshot and push it to Daytona:

```bash
daytona snapshot push custom-alpine:3.21 --name alpine-minimal
```

:::tip
Use the flags `--cpu`, `--memory` and `--disk` to specify the [resources](/docs/en/sandboxes#resources) you want the underlying sandboxes to have. Example:
<br />
```bash
daytona snapshot push custom-alpine:3.21 --name alpine-minimal --cpu 2 --memory 4 --disk 8
```
:::

Alternatively, 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, use the `--context` flag.

```bash
daytona snapshot create my-awesome-snapshot --dockerfile ./Dockerfile
```

```text
Building image from /Users/user/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 images from private registries

Daytona supports creating snapshots from images from [Docker Hub](#docker-hub), [Google Artifact Registry](#google-artifact-registry), [GitHub Container Registry](#github-container-registry-ghcr), [Amazon ECR](#amazon-elastic-container-registry-ecr) or other private container registries.

The **Add Registry** form has a tab per provider — Docker Hub, Google, GitHub, Amazon ECR, and Generic. Select the tab that matches your registry; the form will pre-fill or hide fields whose value is fixed for that provider (so you only fill in what's actually account-specific). The provider-specific sections below list exactly what to enter, and what gets auto-filled behind the scenes.

1. Navigate to [Daytona Registries ↗](https://app.daytona.io/dashboard/registries)
2. Click **Add Registry** and pick the tab for your provider
3. Fill in the visible fields (see the section for your provider below)
4. After the registry is created, navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
5. Click **Create Snapshot**
6. Enter the **snapshot name** and the full **image** reference, including the registry host and repository (e.g. `my-registry.com/<repo>/custom-alpine:3.21`)

Optionally, set the **`CreateSandboxFromSnapshotParams`** field to use the custom snapshot.

#### Docker Hub

Daytona supports creating snapshots from Docker Hub images.

1. On [Daytona Registries ↗](https://app.daytona.io/dashboard/registries), click **Add Registry** and select the **Docker Hub** tab.
2. Fill in:
   - **Username**: your Docker Hub username (the account with access to the image)
   - **Personal Access Token**: a [Docker Hub PAT](https://docs.docker.com/security/access-tokens/) — not your account password

   Registry URL is auto-filled with `docker.io` and not shown in the form.
3. Create the snapshot using the full image reference, e.g. `docker.io/<username>/<image>:<tag>`.

#### Google Artifact Registry

Daytona supports creating snapshots from images from Google Artifact Registry, authenticated with a [service account key](https://cloud.google.com/iam/docs/keys-create-delete) in JSON format.

1. On [Daytona Registries ↗](https://app.daytona.io/dashboard/registries), click **Add Registry** and select the **Google** tab.
2. Fill in:
   - **Registry URL**: the base URL for your region (e.g. `https://us-central1-docker.pkg.dev`)
   - **Service Account JSON Key**: paste the full contents of your service account key JSON file
   - **Google Cloud Project ID**: your GCP project ID

   Username is auto-filled with `_json_key` (required by Google for service-account auth) and not shown in the form.
3. Create the snapshot using the full image reference, e.g. `us-central1-docker.pkg.dev/<project>/<repo>/<image>:<tag>`.

#### GitHub Container Registry (GHCR)

Daytona supports creating snapshots from images from GitHub Container Registry.

1. On [Daytona Registries ↗](https://app.daytona.io/dashboard/registries), click **Add Registry** and select the **GitHub** tab.
2. Fill in:
   - **GitHub Username**: the account with access to the image
   - **Personal Access Token**: a [GitHub PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) with `read:packages` scope (and `write:packages` / `delete:packages` if you'll push or delete)

   Registry URL is auto-filled with `ghcr.io` and not shown in the form.
3. Create the snapshot using the full image reference, e.g. `ghcr.io/<owner>/<image>:<tag>`.

#### Amazon Elastic Container Registry (ECR)

Daytona pulls private ECR images via cross-account IAM role assumption — you create a role in your AWS account that trusts Daytona's broker principal, and Daytona assumes it on every pull to fetch a short-lived ECR token. No long-lived AWS credentials are shared, and no manual token rotation is needed.

You'll need two values:

- **Daytona Broker ARN**: `arn:aws:iam::967657494466:role/DaytonaEcrCredentialBroker` — the IAM principal Daytona uses to assume into your role. Self-hosted: substitute the IAM role your API pods assume (e.g. via IRSA).
- **External ID**: your Daytona organization ID, visible in the dashboard URL (`/dashboard/<orgId>/...`) and on your organization settings page.

##### 1. Create an IAM role in your AWS account

Create an IAM role with the trust and permissions policies below. Replace `<YOUR_EXTERNAL_ID>` with your organization ID.

Trust policy:

```json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::967657494466:role/DaytonaEcrCredentialBroker" },
    "Action": "sts:AssumeRole",
    "Condition": {
      "StringEquals": {
        "sts:ExternalId": "<YOUR_EXTERNAL_ID>"
      }
    }
  }]
}
```

Permissions policy (read-only on ECR):

```json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "ecr:GetAuthorizationToken",
      "ecr:BatchCheckLayerAvailability",
      "ecr:GetDownloadUrlForLayer",
      "ecr:BatchGetImage"
    ],
    "Resource": "*"
  }]
}
```

Copy the ARN of the role you just created (e.g. `arn:aws:iam::123456789012:role/daytona-ecr-puller`).

##### 2. Register the registry in Daytona

1. On [Daytona Registries ↗](https://app.daytona.io/dashboard/registries), click **Add Registry** and select the **Amazon ECR** tab.
2. Fill in:
   - **Registry URL**: `<account_id>.dkr.ecr.<region>.amazonaws.com`
   - **Role ARN**: the role you created in step 1 — Daytona assumes it on every pull

   Password is not used for ECR — Daytona resolves credentials server-side by assuming the role you created in step 1, using your organization ID as the AssumeRole `ExternalId`.

##### 3. Create the snapshot

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots).
2. Click **Create Snapshot**.
3. Enter the snapshot name and the full image reference (e.g. `123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo/custom-alpine:3.21`).

##### Optional: harden the trust policy

Daytona sends a `daytona-<orgId>-pull` session name on every AssumeRole call. You can require it in your trust policy for CloudTrail audit visibility — add inside `Condition`:

```json
"StringLike": {
  "sts:RoleSessionName": "daytona-<YOUR_EXTERNAL_ID>-*"
}
```

### Using the declarative builder

[Declarative Builder](/docs/en/declarative-builder) provides a powerful, code-first approach to defining dependencies for Daytona Sandboxes. Instead of importing images from a container registry, you can programmatically define them using the Daytona [SDKs](/docs/en/getting-started#sdks).

### GPU Snapshots

:::caution[Experimental]
This feature is experimental. To request access, contact [support@daytona.io](mailto:support@daytona.io).
:::

Daytona provides methods to create GPU snapshots using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/snapshots) or programmatically using the Daytona [Python](/docs/en/python-sdk/sync/snapshot), [TypeScript](/docs/en/typescript-sdk/snapshot), [Ruby](/docs/en/ruby-sdk/snapshot), [Go](/docs/en/go-sdk/daytona#SnapshotService), [Java](/docs/en/java-sdk/snapshot) **SDKs**, or [API](/docs/en/tools/api#daytona/tag/snapshots).

GPU snapshots fit into the same snapshot creation flow as other snapshots, but with the additional option to enable the GPU. Create a GPU snapshot first, then use it as the source when creating a [GPU sandbox](/docs/en/sandboxes#gpu-sandboxes).

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
2. Click the **Create Snapshot** button
3. Configure snapshot details and enable the GPU option

To create a GPU-enabled snapshot programmatically, set GPU resources for the snapshot. The `gpu` value defines how many GPU units each sandbox created from this snapshot will request. If `gpu` is not set, it defaults to `0`, which creates a non-GPU snapshot.

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona, CreateSnapshotParams, Resources

daytona = Daytona()
snapshot = daytona.snapshot.create(
    CreateSnapshotParams(
        name="my-gpu-snapshot",
        image="python:3.12",
        resources=Resources(gpu=1),
    ),
)
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from "@daytona/sdk";

const daytona = new Daytona();
const snapshot = await daytona.snapshot.create({
  name: "my-gpu-snapshot",
  image: "python:3.12",
  resources: { gpu: 1 },
});
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
require 'daytona'

daytona = Daytona::Daytona.new
snapshot = daytona.snapshot.create(
  Daytona::CreateSnapshotParams.new(
    name: 'my-gpu-snapshot',
    image: 'python:3.12',
    resources: Daytona::Resources.new(gpu: 1)
  )
)
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
package main

import (
	"context"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
	client, _ := daytona.NewClient()
	ctx := context.Background()
	snapshot, logCh, _ := client.Snapshot.Create(ctx, &types.CreateSnapshotParams{
		Name:  "my-gpu-snapshot",
		Image: "python:3.12",
		Resources: &types.Resources{
			GPU: 1,
		},
	})
	for range logCh {
	}
	_ = snapshot
}
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
import io.daytona.sdk.Daytona;
import io.daytona.sdk.Image;
import io.daytona.sdk.model.Resources;
import io.daytona.sdk.model.Snapshot;

final class CreateGpuSnapshot {
    public static void main(String[] args) {
        try (Daytona daytona = new Daytona()) {
            Resources resources = new Resources();
            resources.setGpu(1);
            Snapshot snapshot = daytona.snapshot().create(
                "my-gpu-snapshot",
                Image.base("python:3.12"),
                resources,
                null
            );
        }
    }
}
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-gpu-snapshot",
    "imageName": "python:3.12",
    "gpu": 1
  }'
```

</TabItem>
</Tabs>

##### GPU Snapshot requirements

Building a custom image for a GPU snapshot requires Ubuntu 24.04 and compatible NVIDIA userspace packages. Include the following in your snapshot Dockerfile:

```dockerfile
ARG NVIDIA_DRIVER_VERSION=580.126.20
ARG UBUNTU_PKG_SUFFIX=0ubuntu0.24.04.2

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update -qq \
 && apt-get install -y -qq --no-install-recommends \
      nvidia-utils-580-server=${NVIDIA_DRIVER_VERSION}-${UBUNTU_PKG_SUFFIX} \
      libnvidia-compute-580-server=${NVIDIA_DRIVER_VERSION}-${UBUNTU_PKG_SUFFIX} \
      python3 \
      ca-certificates \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

COPY verify-cuda.sh /verify-cuda.sh
RUN chmod +x /verify-cuda.sh

LABEL nvidia.driver.version="${NVIDIA_DRIVER_VERSION}"
```

### Resources

Snapshots can be customized with specific [sandbox resources](/docs/en/sandboxes#resources). By default, Daytona sandboxes use **1 vCPU**, **1GB RAM**, and **3GiB disk**. To view your available resources and limits, see [limits](/docs/en/limits) or navigate to [Daytona Limits ↗](https://app.daytona.io/dashboard/limits).

To set custom sandbox resources, use the `Resources` class.

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona, CreateSnapshotParams, Resources

daytona = Daytona()
snapshot = daytona.snapshot.create(
    CreateSnapshotParams(
        name="my-awesome-snapshot",
        image="python:3.12",
        resources=Resources(cpu=2, memory=4, disk=8),
    ),
)
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from "@daytona/sdk";

const daytona = new Daytona();
const snapshot = await daytona.snapshot.create({
  name: "my-awesome-snapshot1123",
  image: "python:3.12",
  resources: { cpu: 2, memory: 4, disk: 8 },
});
```

  </TabItem>

  <TabItem label="Ruby" icon="seti:ruby">

```ruby
require 'daytona'

daytona = Daytona::Daytona.new
snapshot = daytona.snapshot.create(
  Daytona::CreateSnapshotParams.new(
    name: 'my-awesome-snapshot',
    image: 'python:3.12',
    resources: Daytona::Resources.new(
      cpu: 2,
      memory: 4,
      disk: 8
    )
  )
)
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
package main

import (
	"context"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona"
	"github.com/daytonaio/daytona/libs/sdk-go/pkg/types"
)

func main() {
	client, _ := daytona.NewClient()
	ctx := context.Background()
	snapshot, logCh, _ := client.Snapshot.Create(ctx, &types.CreateSnapshotParams{
		Name:  "my-awesome-snapshot",
		Image: "python:3.12",
		Resources: &types.Resources{
			CPU:    2,
			Memory: 4,
			Disk:   8,
		},
	})
	for range logCh {
	}
	_ = snapshot
}
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
import io.daytona.sdk.Daytona;
import io.daytona.sdk.Image;
import io.daytona.sdk.model.Resources;
import io.daytona.sdk.model.Snapshot;

final class CreateSnapshotResources {
    public static void main(String[] args) {
        try (Daytona daytona = new Daytona()) {
            Resources resources = new Resources();
            resources.setCpu(2);
            resources.setMemory(4);
            resources.setDisk(8);
            Snapshot snapshot = daytona.snapshot().create(
                "my-awesome-snapshot",
                Image.base("python:3.12"),
                resources,
                null
            );
        }
    }
}
```

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
daytona snapshot create my-awesome-snapshot --image python:3.11-slim --cpu 2 --memory 4 --disk 8
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-awesome-snapshot",
    "imageName": "python:3.11-slim",
    "cpu": 2,
    "memory": 4,
    "disk": 8
  }'
```

</TabItem>
</Tabs>

### Regions

When creating a snapshot, you can specify the [region](/docs/en/regions) in which it will be available. If not specified, the snapshot will be created in your organization's default region. When you later create a sandbox from this snapshot, you can use the snapshot's region as the target region for the sandbox.

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona, CreateSnapshotParams

daytona = Daytona()
snapshot = daytona.snapshot.create(
    CreateSnapshotParams(
        name="my-awesome-snapshot",
        image="python:3.12",
        region_id="eu",
    ),
)
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from "@daytona/sdk";

const daytona = new Daytona();
const snapshot = await daytona.snapshot.create({
  name: "my-awesome-snapshotus",
  image: "python:3.12",
  regionId: "us",
});
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
require 'daytona'

daytona = Daytona::Daytona.new
snapshot = daytona.snapshot.create(
  Daytona::CreateSnapshotParams.new(
    name: 'my-awesome-snapshot',
    image: 'python:3.12',
    region_id: 'us'
  )
)
```

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
daytona snapshot create my-awesome-snapshot --image python:3.11-slim --region us
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
    "name": "my-awesome-snapshot",
    "imageName": "python:3.11-slim",
    "regionId": "us"
  }'
```

</TabItem>
</Tabs>

## Get a Snapshot by name

Daytona provides an option to get a snapshot by name.

The following snippet returns the snapshot with the specified name:

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
daytona.snapshot.get("my-awesome-snapshot")
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
await daytona.snapshot.get('my-awesome-snapshot')
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
daytona.snapshot.get('my-awesome-snapshot')
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
_, err := client.Snapshots.Get(ctx, "my-awesome-snapshot")
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
daytona.snapshot().get("my-awesome-snapshot");
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots/my-awesome-snapshot \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```

</TabItem>
</Tabs>

## List Snapshots

Daytona provides options to list snapshots and view their details.

The following snippet lists all snapshots on the first page with a limit of 10 snapshots per page.

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
daytona.snapshot.list(page=2, limit=10)
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
await daytona.snapshot.list(2, 10)
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
daytona.snapshot.list(page: 2, limit: 10)
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
page, limit := 2, 10
_, err := client.Snapshots.List(ctx, &page, &limit)
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
daytona.snapshot().list(2, 10);
```

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
# List snapshots with pagination
daytona snapshot list --page 2 --limit 10
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl 'https://app.daytona.io/api/snapshots?page=2&limit=10' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```

</TabItem>
</Tabs>

## Activate Snapshots

Snapshots automatically become inactive after 2 weeks of not being used. To activate an inactive snapshot:

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
2. Click the three dots at the end of the row for the snapshot you want to activate
3. Click the **Activate** button

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">
```python
daytona.snapshot.activate("my-awesome-snapshot")
```
</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">
```typescript
await daytona.snapshot.activate("my-awesome-snapshot")
```
</TabItem>
<TabItem label="Ruby" icon="seti:ruby">
```ruby
daytona.snapshot.activate('my-awesome-snapshot')
```
</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots/my-inactive-snapshot/activate \
  --request POST \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```

</TabItem>
</Tabs>

## Deactivate Snapshots

Daytona provides an option to deactivate snapshots. Deactivated snapshots are not available for new sandboxes.

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
2. Click the three dots at the end of the row for the snapshot you want to deactivate
3. Click the **Deactivate** button

## Delete Snapshots

Daytona provides options to delete snapshots. Deleted snapshots cannot be recovered.

1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)
2. Click the three dots at the end of the row for the snapshot you want to delete
3. Click the **Delete** button

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
daytona.snapshot.delete(daytona.snapshot.get("my-awesome-snapshot"))
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
await daytona.snapshot.delete(await daytona.snapshot.get("my-awesome-snapshot"))
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
daytona.snapshot.delete(daytona.snapshot.get('my-awesome-snapshot'))
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
snapshot, err := client.Snapshots.Get(ctx, "my-awesome-snapshot")
err = client.Snapshots.Delete(ctx, snapshot)
```

</TabItem>
<TabItem label="Java" icon="seti:java">

```java
daytona.snapshot().delete(daytona.snapshot().get("my-awesome-snapshot").getId());
```

</TabItem>
<TabItem label="CLI" icon="seti:shell">

```bash
daytona snapshot delete my-awesome-snapshot
```

</TabItem>
<TabItem label="API" icon="seti:json">

```bash
curl https://app.daytona.io/api/snapshots/my-awesome-snapshot \
  --request DELETE \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'
```

</TabItem>
</Tabs>

## Run 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. The following use cases are supported:

- 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.
:::

#### Create a Docker-in-Docker Snapshot

Daytona provides an option to 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

##### Using manual installation

Alternatively, 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 -
```

#### Run Docker Compose in a Sandbox

Docker Compose allows you to define and run multi-container applications. With Docker-in-Docker enabled in a Daytona Sandbox, you can use Docker Compose to orchestrate services like databases, caches, and application containers.

First, create a Docker-in-Docker snapshot using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/snapshots) or [CLI](/docs/en/tools/cli#daytona-snapshot-create) with one of the [pre-built images](#using-pre-built-images) (e.g., `docker:28.3.3-dind`). Then use the following snippet to run Docker Compose services inside a sandbox:

<Tabs syncKey="language">
<TabItem label="Python" icon="seti:python">

```python
from daytona import Daytona, CreateSandboxFromSnapshotParams

# Initialize the Daytona client
daytona = Daytona()

# Create a sandbox from a Docker-in-Docker snapshot
sandbox = daytona.create(CreateSandboxFromSnapshotParams(snapshot='docker-dind'))

# Create a docker-compose.yml file
compose_content = '''
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
'''
sandbox.fs.upload_file(compose_content.encode(), 'docker-compose.yml')

# Start Docker Compose services
result = sandbox.process.exec('docker compose -p demo up -d')
print(result.result)

# Check running services
result = sandbox.process.exec('docker compose -p demo ps')
print(result.result)

# Clean up
sandbox.process.exec('docker compose -p demo down')
```

</TabItem>
<TabItem label="TypeScript" icon="seti:typescript">

```typescript
import { Daytona } from '@daytona/sdk'

// Initialize the Daytona client
const daytona = new Daytona()

// Create a sandbox from a Docker-in-Docker snapshot
const sandbox = await daytona.create({ snapshot: 'docker-dind' })

// Create a docker-compose.yml file
const composeContent = `
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
`
await sandbox.fs.uploadFile(Buffer.from(composeContent), 'docker-compose.yml')

// Start Docker Compose services
let result = await sandbox.process.executeCommand('docker compose -p demo up -d')
console.log(result.result)

// Check running services
result = await sandbox.process.executeCommand('docker compose -p demo ps')
console.log(result.result)

// Clean up
await sandbox.process.executeCommand('docker compose -p demo down')
```

</TabItem>
<TabItem label="Ruby" icon="seti:ruby">

```ruby
require 'daytona'

# Initialize the Daytona client
daytona = Daytona::Daytona.new

# Create a sandbox from a Docker-in-Docker snapshot
sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(snapshot: 'docker-dind'))

# Create a docker-compose.yml file
compose_content = <<~YAML
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
YAML
sandbox.fs.upload_file(compose_content, 'docker-compose.yml')

# Start Docker Compose services
result = sandbox.process.exec(command: 'docker compose -p demo up -d')
puts result.result

# Check running services
result = sandbox.process.exec(command: 'docker compose -p demo ps')
puts result.result

# Clean up
sandbox.process.exec(command: 'docker compose -p demo down')
```

</TabItem>
<TabItem label="Go" icon="seti:go">

```go
package main

import (
	"context"
	"fmt"

	"github.com/daytonaio/sdk-go/daytona"
	"github.com/daytonaio/sdk-go/types"
)

func main() {
	ctx := context.Background()

	// Initialize the Daytona client
	client, _ := daytona.NewDaytona(nil)

	// Create a sandbox from a Docker-in-Docker snapshot
	sandbox, _ := client.Create(ctx, &types.CreateSandboxFromSnapshotParams{
		Snapshot: daytona.Ptr("docker-dind"),
	}, nil)

	// Create a docker-compose.yml file
	composeContent := `
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
`
	sandbox.Fs.UploadFile(ctx, []byte(composeContent), "docker-compose.yml")

	// Start Docker Compose services
	result, _ := sandbox.Process.ExecuteCommand(ctx, "docker compose -p demo up -d", nil)
	fmt.Println(result.Result)

	// Check running services
	result, _ = sandbox.Process.ExecuteCommand(ctx, "docker compose -p demo ps", nil)
	fmt.Println(result.Result)

	// Clean up
	sandbox.Process.ExecuteCommand(ctx, "docker compose -p demo down", nil)
}
```

</TabItem>
</Tabs>

## Run Kubernetes in a Sandbox

Daytona Sandboxes can run a Kubernetes cluster inside the sandbox. Kubernetes runs entirely inside the sandbox and is removed when the sandbox is deleted, keeping environments secure and reproducible.

##### Run k3s in a Sandbox

The following snippet installs and starts a k3s cluster inside a sandbox and lists all running pods.

```typescript
import { Daytona } from '@daytona/sdk'
import { setTimeout } from 'timers/promises'

// Initialize the Daytona client
const daytona = new Daytona()

// Create the sandbox instance
const sandbox = await daytona.create()

// Run the k3s installation script
const response = await sandbox.process.executeCommand(
  'curl -sfL https://get.k3s.io | sh -'
)

// Run k3s
const sessionName = 'k3s-server'
await sandbox.process.createSession(sessionName)
const k3s = await sandbox.process.executeSessionCommand(sessionName, {
  command: 'sudo /usr/local/bin/k3s server',
  async: true,
})

// Give time to k3s to fully start
await setTimeout(30000)

// Get all pods
const pods = await sandbox.process.executeCommand(
  'sudo /usr/local/bin/kubectl get pod -A'
)
console.log(pods.result)
```

## Default Snapshots

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. Daytona provides three default snapshot sizes:

| **Snapshot**         | **vCPU** | **Memory** | **Storage** |
| -------------------- | -------- | ---------- | ----------- |
| **`daytona-small`**  | 1        | 1GiB       | 3GiB        |
| **`daytona-medium`** | 2        | 4GiB       | 8GiB        |
| **`daytona-large`**  | 4        | 8GiB       | 10GiB       |

All default snapshots are based on the `daytonaio/sandbox:<version>` image. For more information, see the [Dockerfile](https://github.com/daytonaio/daytona/blob/main/images/sandbox/Dockerfile).

### Python packages (pip)

- `anthropic` (v0.76.0)
- `beautifulsoup4` (v4.14.3)
- `claude-agent-sdk` (v0.1.22)
- `openai-agents` (v0.15.1)
- `daytona` (v0.134.0)
- `django` (v6.0.1)
- `flask` (v3.1.2)
- `huggingface-hub` (v0.36.0)
- `instructor` (v1.14.4)
- `keras` (v3.13.0)
- `langchain` (v1.2.7)
- `llama-index` (v0.14.13)
- `matplotlib` (v3.10.8)
- `numpy` (v2.4.1)
- `ollama` (v0.6.1)
- `openai` (v2.33.0)
- `opencv-python` (v4.13.0.90)
- `pandas` (v2.3.3)
- `pillow` (v12.1.0)
- `pydantic-ai` (v1.47.0)
- `requests` (v2.32.5)
- `scikit-learn` (v1.8.0)
- `scipy` (v1.17.0)
- `seaborn` (v0.13.2)
- `sqlalchemy` (v2.0.46)
- `torch` (v2.10.0)
- `transformers` (v4.57.6)

### Node.js packages (npm)

- `@anthropic-ai/claude-code` (v2.1.19)
- `@openai/codex` (0.128.0)
- `bun` (v1.3.6)
- `openclaw` (v2026.2.1)
- `opencode-ai` (v1.1.35)
- `ts-node` (v10.9.2)
- `typescript` (v5.9.3)
- `typescript-language-server` (v5.1.3)

