Skip to content

Snapshots

View as Markdown

Snapshots are reusable sandbox templates built from Docker or OCI compatible images. Sandboxes can use snapshots to provide a consistent and reproducible environment for your dependencies, settings, and resources.

A snapshot defines the base operating system, language runtimes, system packages, and project-level setup that should exist when a sandbox starts. Instead of repeating bootstrap steps on every sandbox creation, you capture that setup once as a snapshot and reuse it.

You start with default snapshots for common stacks, or create custom snapshots for your own toolchain and constraints. Custom snapshots are useful when your workflow depends on specific package versions, private dependencies, startup scripts, or filesystem layout.

Daytona provides methods to create snapshots. You can create a snapshot from:

  1. Navigate to Daytona Snapshots ↗
  2. Click Create Snapshot
  3. Enter the snapshot name and image
  • Snapshot name: identifier used to reference the snapshot
  • Snapshot image: base image for the snapshot, must include either a tag or a digest (e.g., ubuntu:22.04); the latest/lts/stable tags are not supported
  1. Click Create to create a snapshot
from daytona import Daytona, CreateSnapshotParams
daytona = Daytona()
snapshot = daytona.snapshot.create(
CreateSnapshotParams(name="my-awesome-snapshot", image="python:3.12"),
)

Daytona provides methods to create GPU snapshots.

GPU snapshots are used to create GPU sandboxes. Daytona provides a pre-built daytona-gpu snapshot for creating GPU sandboxes.

  1. Navigate to Daytona Snapshots ↗
  2. Click Create Snapshot
  3. Enter the snapshot name and image
  4. Select us-east-1 region
  5. Select the Allocate GPU checkbox
  6. Click Create to create a GPU snapshot
from daytona import CreateSnapshotParams, Daytona, DaytonaConfig, Image, Resources
daytona = Daytona(DaytonaConfig(target="us-east-1"))
snapshot = daytona.snapshot.create(
CreateSnapshotParams(
name="my-gpu-snapshot",
image=Image.base("python:3.12"),
resources=Resources(cpu=1, memory=1, disk=1, gpu=1),
),
)

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

  1. Navigate to Daytona Snapshots ↗
  2. Click the Create Snapshot button
  3. Enter the snapshot name and image of any publicly accessible image or container registry
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=""),
)

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.

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
Terminal window
docker images
  1. Create a snapshot and push it to Daytona:
Terminal window
daytona snapshot push custom-alpine:3.21 --name alpine-minimal

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.

Terminal window
daytona snapshot create my-awesome-snapshot --dockerfile ./Dockerfile

Daytona supports creating snapshots from images from Docker Hub, Google Artifact Registry, GitHub Container Registry, Amazon ECR or other private container registries.

  1. Navigate to Daytona Registries ↗
  2. Click Add Registry and select your provider
  3. Fill in the visible fields
  4. Navigate to Daytona 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)

Daytona supports creating snapshots from Docker Hub images.

  1. Navigate to Daytona Registries ↗,
  2. Click Add Registry and select the Docker Hub tab
  3. Input the following fields:
    • Username: your Docker Hub username (the account with access to the image)
    • Personal Access Token: a Docker Hub PAT — not your account password
    • Registry URL: auto-filled with docker.io and not shown in the form
  4. Create the snapshot using the full image reference, e.g. docker.io/<username>/<image>:<tag>

Daytona supports creating snapshots from images from Google Artifact Registry, authenticated with a service account key in JSON format.

  1. Navigate to Daytona Registries ↗,

  2. Click Add Registry and select the Google tab

  3. Input the following fields:

    • Registry URL: the base URL for your region (e.g. https://us-central1-docker.pkg.dev)
    • Service Account JSON Key: the contents of your service account key JSON file
    • Google Cloud Project ID: your GCP project ID
    • Username: auto-filled with _json_key (required by Google for service-account auth)
  4. Create the snapshot using the full image reference, e.g.

    us-central1-docker.pkg.dev/<project>/<repo>/<image>:<tag>

Daytona supports creating snapshots from images from GitHub Container Registry.

  1. Navigate to Daytona Registries ↗,

  2. Click Add Registry and select the GitHub tab

  3. Input the following fields:

    • GitHub Username: the account with access to the image
    • Personal Access Token: a GitHub PAT with read:packages scope (and write:packages / delete:packages if you’ll push or delete)
    • Registry URL: auto-filled with ghcr.io and not shown in the form
  4. Create the snapshot using the full image reference, e.g.

    ghcr.io/<owner>/<image>:<tag>

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.

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

Trust policy:

{
"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):

{
"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).

  1. On Daytona 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.

  1. Navigate to Daytona 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).

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:

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

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.

Snapshots can be customized with specific sandbox resources. By default, Daytona sandboxes use 1 vCPU, 1GB RAM, and 3GiB disk. To view your available resources and limits, see limits or navigate to Daytona Limits ↗.

To set custom snapshot resources, use the Resources class.

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),
),
)

When creating a snapshot, you can specify the region 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.

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

Daytona provides an option to get a snapshot by name.

The following snippet returns the snapshot with the specified name:

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

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.

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

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

  1. Navigate to Daytona Snapshots ↗
  2. Click the three dots at the end of the row for the snapshot you want to activate
  3. Click the Activate button
daytona.snapshot.activate("my-awesome-snapshot")

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

  1. Navigate to Daytona Snapshots ↗
  2. Click the three dots at the end of the row for the snapshot you want to deactivate
  3. Click the Deactivate button

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

  1. Navigate to Daytona Snapshots ↗
  2. Click the three dots at the end of the row for the snapshot you want to delete
  3. Click the Delete button
daytona.snapshot.delete(daytona.snapshot.get("my-awesome-snapshot"))

A snapshot can have several different states. Each state reflects the snapshot’s current status.

  • 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

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

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.

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

Alternatively, install Docker manually in a custom Dockerfile:

FROM ubuntu:22.04
# Install Docker using the official install script
RUN curl -fsSL https://get.docker.com | VERSION=28.3.3 sh -

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 ↗ or CLI with one of the pre-built images (e.g., docker:28.3.3-dind). Then use the following snippet to run Docker Compose services inside a sandbox:

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')

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.

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

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)

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:

SnapshotvCPUMemoryStorage
daytona-small11GiB3GiB
daytona-medium24GiB8GiB
daytona-large48GiB10GiB

All default snapshots are based on the daytonaio/sandbox:<version> image. For more information, see the Dockerfile.

  • 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)
  • pipx (v1.8.0)
  • pydantic-ai (v1.47.0)
  • python-lsp-server (v1.14.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)
  • uv (v0.9.26)
  • @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)