---
title: 宣言的ビルダー
---

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

Daytona（サンドボックスの作成・管理プラットフォーム）の宣言的ビルダーは、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）の依存関係をコードファーストで定義する強力な手法を提供します。コンテナレジストリからイメージを取り込む代わりに、SDKを用いてプログラム的に定義できます。

## 概要

宣言的ビルダーシステムは、主に次の2つのワークフローをサポートします。

1. **動的イメージ**: サンドボックス（Daytonaが管理する隔離された一時的な実行環境）作成時に、依存関係の異なるイメージをオンデマンドでビルド
2. **事前構築済みスナップショット**: 複数のサンドボックスで共有可能な、すぐに使えるスナップショット（サンドボックス作成に使う事前設定済みの再利用可能なイメージ／テンプレート）を作成・登録

以下の機能を提供します。完全なAPIリファレンスとメソッドシグネチャについては、[Python](/docs/ja/python-sdk/common/image) および [TypeScript](/docs/ja/typescript-sdk/image) のSDKリファレンスを参照してください。

### ベースイメージの選択

- **Debianベースの環境**（Pythonと必須のビルドツールをプリインストール）
- **カスタムベースイメージ**（任意のDockerレジストリまたは既存のコンテナイメージ由来）
- **Dockerfileの取り込み**（既存のDockerfileのインポートと拡張）

### パッケージ管理

- **Pythonパッケージのインストール**（`pip`、`requirements.txt`、`pyproject.toml`に対応）
- **高度なpipオプション**（カスタムインデックス、find-links、オプション依存関係など）

### ファイルシステム操作

- **ファイルのコピー**（ローカル開発環境からイメージへ）
- **ディレクトリのコピー**（大量ファイル転送やプロジェクトセットアップに対応）
- **作業ディレクトリの設定**（デフォルトの実行コンテキストを指定）

### 環境構成

- **環境変数**（アプリケーション設定やシークレット用）
- **シェルコマンドの実行**（イメージビルド中）
- **コンテナのランタイム設定**（エントリポイントやデフォルトコマンドを含む）

詳細なメソッドシグネチャや使用例については、[Python](/docs/ja/python-sdk/common/image) および [TypeScript](/docs/ja/typescript-sdk/image) のSDKリファレンスを参照してください。

## 動的イメージビルド

サンドボックス作成時に、その場でイメージを生成できます。既存のどのイメージにも含まれていない特定の依存関係を持つ新しいサンドボックスを用意したい場合に有用です。

新規のイメージを定義することも、既存のイメージに特定の依存関係を追加することも可能です（例: `pip` パッケージや `apt-get install` コマンド）。\
これにより、ビルド処理のために自前のコンピュートリソースを使う必要がなくなり、Daytonaのインフラストラクチャにオフロードできます。\
各バージョンごとに個別のスナップショットを登録・検証する必要もありません。依存関係リストを素早く反復しやすくなり、また、数十〜数百の類似ユースケース/セットアップ向けにわずかに異なるバージョンを用意することもできます。

<Tabs syncKey="language">
  <TabItem label="Python" icon="seti:python">
    ```python
    # Define the dynamic image
    dynamic_image = (
        Image.debian_slim("3.12")
        .pip_install(["pytest", "pytest-cov", "mypy", "ruff", "black", "gunicorn"])
        .run_commands("apt-get update && apt-get install -y git curl", "mkdir -p /home/daytona/project")
        .workdir("/home/daytona/project")
        .env({"ENV_VAR": "My Environment Variable"})
        .add_local_file("file_example.txt", "/home/daytona/project/file_example.txt")
    )

    # Create a new Sandbox with the dynamic image and stream the build logs

    sandbox = daytona.create(
        CreateSandboxFromImageParams(
            image=dynamic_image,
        ),
        timeout=0,
        on_snapshot_create_logs=print,
    )

    ```
  </TabItem>

  <TabItem label="TypeScript" icon="seti:typescript">
    ```typescript
    // Define the dynamic image
    const dynamicImage = Image.debianSlim('3.13')
        .pipInstall(['pytest', 'pytest-cov', 'black', 'isort', 'mypy', 'ruff'])
        .runCommands('apt-get update && apt-get install -y git', 'mkdir -p /home/daytona/project')
        .workdir('/home/daytona/project')
        .env({
          NODE_ENV: 'development',
        })
        .addLocalFile('file_example.txt', '/home/daytona/project/file_example.txt')

    // Create a new Sandbox with the dynamic image and stream the build logs
    const sandbox = await daytona.create(
      {
        image: dynamicImage,
      },
      {
        timeout: 0,
        onSnapshotCreateLogs: console.log,
      }
    )
    ```
  </TabItem>
</Tabs>

:::tip
動的イメージからのサンドボックス作成を一度実行すると、そのイメージは24時間キャッシュされ、同じランナー上での後続のサンドボックス作成はほぼ即時に完了します。

つまり、毎回同じスクリプトを使えば、Daytonaがイメージのキャッシュを適切に処理します。
:::

## 事前ビルド済みスナップショットの作成

特定の依存関係を含む新しいDaytonaのスナップショットを準備し、必要なときに複数のサンドボックスで即座に使いたい場合は、事前ビルド済みのスナップショットを作成できます。

このスナップショットはDaytonaダッシュボード上に表示され続け、永続的にキャッシュされるため、再ビルドは不要です。

<Tabs syncKey="language">
  <TabItem label="Python" icon="seti:python">
    ```python
    # スナップショット用の一意の名前を生成
    snapshot_name = f"python-example:{int(time.time())}"

    # イメージに追加するデータを含むローカルファイルを作成

    with open("file_example.txt", "w") as f:
        f.write("Hello, World!")

    # 一般的なデータサイエンスパッケージを含むPythonイメージを作成

    image = (
        Image.debian_slim("3.12")
        .pip_install(["numpy", "pandas", "matplotlib", "scipy", "scikit-learn", "jupyter"])
        .run_commands(
            "apt-get update && apt-get install -y git",
            "groupadd -r daytona && useradd -r -g daytona -m daytona",
            "mkdir -p /home/daytona/workspace",
        )
        .dockerfile_commands(["USER daytona"])
        .workdir("/home/daytona/workspace")
        .env({"MY_ENV_VAR": "My Environment Variable"})
        .add_local_file("file_example.txt", "/home/daytona/workspace/file_example.txt")
    )

    # スナップショットを作成し、ビルドログをストリーミング出力

    print(f"=== Creating Snapshot: {snapshot_name} ===")
    daytona.snapshot.create(
        CreateSnapshotParams(
            name=snapshot_name,
            image=image,
            resources=Resources(
                cpu=1,
                memory=1,
                disk=3,
            ),
        ),
        on_logs=print,
    )

    # 事前ビルド済みのスナップショットを使って新しいサンドボックスを作成

    sandbox = daytona.create(
        CreateSandboxFromSnapshotParams(
            snapshot=snapshot_name
        )
    )

    ```
  </TabItem>

  <TabItem label="TypeScript" icon="seti:typescript">
    ```typescript
    // イメージ用の一意の名前を生成
    const snapshotName = `node-example:${Date.now()}`
    console.log(`Creating Snapshot with name: ${snapshotName}`)

    // スナップショットに追加するデータを含むローカルファイルを作成
    const localFilePath = 'file_example.txt'
    const localFileContent = 'Hello, World!'
    fs.writeFileSync(localFilePath, localFileContent)

    // 一般的なデータサイエンスパッケージを含むPythonイメージを作成
    const image = Image.debianSlim('3.12')
        .pipInstall(['numpy', 'pandas', 'matplotlib', 'scipy', 'scikit-learn'])
        .runCommands(
          'apt-get update && apt-get install -y git',
          'groupadd -r daytona && useradd -r -g daytona -m daytona',
          'mkdir -p /home/daytona/workspace'
        )
        .dockerfileCommands(['USER daytona'])
        .workdir('/home/daytona/workspace')
        .env({
            MY_ENV_VAR: 'My Environment Variable',
        })
        .addLocalFile(localFilePath, '/home/daytona/workspace/file_example.txt')

    # スナップショットを作成し、ビルドログをストリーミング出力
    console.log(`=== Creating Snapshot: ${snapshotName} ===`)
    await daytona.snapshot.create(
        {
          name: snapshotName,
          image,
          resources: {
            cpu: 1,
            memory: 1,
            disk: 3,
          },
        },
        {
          onLogs: console.log,
        },
      )

    // 事前ビルド済みのスナップショットを使って新しいサンドボックスを作成
    const sandbox = await daytona.create({
        snapshot: snapshotName,
    })
    ```
  </TabItem>
</Tabs>

## 既存の Dockerfile を利用する

既存の Dockerfile をイメージのベースとして使いたい場合は、次のようにインポートできます。

<Tabs syncKey="language">
  <TabItem label="Python" icon="seti:python">
    ```python
    image = Image.from_dockerfile("app/Dockerfile").pip_install(["numpy"])
    ```
  </TabItem>

  <TabItem label="TypeScript" icon="seti:typescript">
    ```typescript
    const image = Image.fromDockerfile("app/Dockerfile").pipInstall(['numpy'])
    ```
  </TabItem>
</Tabs>

## ベストプラクティス

1. **レイヤー最適化**: 関連する操作をまとめて、Dockerのレイヤー数を抑える
2. **キャッシュの活用**: 同一のビルドコマンドとコンテキストはキャッシュされ、以降のビルドはほぼ即時に完了する
3. **セキュリティ**: アプリケーションのワークロード用に非rootユーザーを作成する
4. **リソース効率**: 適切な場合はスリムなベースイメージを使用する
5. **コンテキストの最小化**: ビルドコンテキストには必要なファイルだけを含める

宣言的ビルダーは、Dockerの強力さと柔軟性を損なうことなく、コンテナイメージ作成に対するプログラム的で保守しやすいアプローチを提供し、開発ワークフローを効率化します。
