harness.run の Docker サンドボックス

エージェントハーネスを Docker サンドボックス内で実行する。

DaguはDAG全体、または1つのharness.runステップだけにDockerコンテナを起動できます。ファイルシステムのマウント、環境変数、ネットワーク、プロバイダCLIはすべてcontainer設定で明示します。

共有Dockerサンドボックス
type: graph

container:
  image: alpine:3.20
  pull_policy: missing
  working_dir: /workspace
  volumes:
    - .:/workspace
  env:
    - SMOKE_TOKEN=container-env-ok

harnesses:
  shell:
    binary: sh
    prefix_args:
      - -c
    prompt_mode: arg

steps:
  - id: write_file
    run: echo "from command step" > shared.txt

  - id: read_file
    action: harness.run
    with:
      provider: shell
      prompt: |
        set -eu
        cat shared.txt
        echo "SMOKE_TOKEN=$SMOKE_TOKEN"
        cat /etc/alpine-release

ルートレベルcontainerではコマンドステップとharnessステップが同じファイルシステムを共有します。

ステップレベルcontainerでは1回のharness実行だけを専用イメージとマウントで隔離します。

DAGU_CONTAINER_RUNTIMEが未設定の場合、Dockerが既定のランタイムです。

Alpineの例はモデルプロバイダを呼ばずにコンテナ経路を確認します。

01

コンテナの範囲

コマンドステップとharnessステップでファイルやツールを共有したい場合はルートレベルcontainerを使います。1つのエージェント実行だけにイメージ、workspace、認証情報を渡したい場合はステップレベルcontainerを使います。

  • ルートレベルcontainerは継承されるコマンドステップとCLIベースのharness.runに適用されます。
  • ステップレベルcontainerは、そのステップではルートレベルcontainerより優先されます。
  • 既存の名前付きコンテナにも接続できますが、再現性のあるエージェントランナーにはimage指定の方が明確です。
02

エージェントのネットワーク

Codex、Claude Code、OpenCodeなどのホスト型エージェントCLIは、通常プロバイダAPIへ到達する外向きネットワークが必要です。Daguが設定するのはコンテナのネットワークモードであり、許可や拒否の制御はDocker、Podman、ファイアウォール、プロキシ側で行います。

  • Dockerの既定ネットワークを使う場合はcontainer.networkを省略します。必要な外向き通信を持つカスタムネットワークを指定することもできます。
  • 許可/拒否の制御にはDockerまたはPodmanのネットワーク、ファイアウォールルール、プロキシ環境変数を使います。
  • `network: none`は外部サービスを一切呼ばないコマンド用です。ホスト型エージェントの例としては使いません。
03

ランタイム環境

ランを実行するDaguプロセス、つまりserver、scheduler、worker、CLIにコンテナランタイムを設定します。Dockerは既定で選ばれ、DOCKER_HOSTなど標準のDocker環境変数も使われます。

  • 明示したい場合だけDAGU_CONTAINER_RUNTIME=dockerを設定します。
  • Dagu自体をDockerで動かす場合、Dockerソケットは信頼できるDagu workerにだけマウントします。
  • エージェント自身がコンテナを操作しない限り、ランナーコンテナにDockerソケットは不要です。
04

認証情報

認証情報は暗黙には渡りません。container.envで渡すか、プロバイダが実際に読む認証ディレクトリをマウントします。ルートレベルcontainerの認証情報は、共有コンテナ内の継承ステップすべてから読めます。