Dagger——Docker創業者が挑むCI/CDの「Write Once, Run Anywhere」
「CI/CDパイプラインを書き直すのは、もうごめんだ」——GitHub ActionsからGitLab CIへ、JenkinsからCircleCIへ。CI/CDプラットフォームを変えるたびに、パイプラインの定義ファイルを一から書き直す。この「CI/CDベンダーロックイン」問題に、Docker創業者のSolomon Hykesが解決策を提示している。
Daggerは、CI/CDパイプラインをGo、Python、TypeScriptなどのプログラミング言語で記述し、コンテナ内で実行するフレームワークだ。パイプラインの定義がYAMLではなくコードであるため、ローカルでもCI/CDサービス上でも全く同じ動作が保証される。2026年3月時点でDagger 1.x系がリリースされ、シリーズBで$30M(約45億円)の資金調達を完了、エンタープライズ採用が本格化している。
CI/CDの何が問題なのか
YAML地獄とプラットフォーム依存
現代のCI/CDの最大の問題は、パイプライン定義がプラットフォーム固有であることだ。
以下の図は、従来のCI/CDとDaggerのアプローチの違いを示しています。
同じ「ビルド → テスト → デプロイ」のパイプラインを構築するのに、GitHub ActionsではYAML、JenkinsではGroovy、GitLab CIではまた別のYAML構文で記述する必要がある。さらに深刻な問題がある。
- ローカル再現性ゼロ: CI/CDで失敗したパイプラインをローカルで再現・デバッグできない。「Push → CI失敗 → 修正 → Push → CI失敗...」のフィードバックループが長い
- テスト不能: YAMLで記述されたパイプラインにはユニットテストを書けない
- コードの再利用困難: 関数、クラス、パッケージといったプログラミングの基本概念が使えない
- Secret管理の分散: CI/CDプラットフォームごとにシークレット管理が異なる
「Works on my CI」問題
ローカル開発環境では動くのにCIでは動かない(またはその逆)。この問題の根本原因は、CI/CD環境とローカル環境が全く異なる実行環境であることだ。
Daggerの仕組み
コアコンセプト
Daggerは3つの要素で構成される。
- Dagger Engine: BuildKit(Dockerのビルドエンジン)をベースにした実行環境。すべてのパイプラインステップがコンテナ内で実行される
- Dagger SDKs: Go、Python、TypeScript、Elixir、PHP、Java等のSDK。パイプラインをネイティブコードで記述
- Dagger Cloud: パイプラインの可視化、キャッシング、チームコラボレーション(オプション)
コード例:TypeScript
import { connect } from "@dagger.io/dagger"
connect(async (client) => {
// ソースコードをロード
const source = client.host().directory(".", {
exclude: ["node_modules", ".git"]
})
// Node.js コンテナでビルド
const runner = client
.container()
.from("node:20-slim")
.withDirectory("/app", source)
.withWorkdir("/app")
.withExec(["npm", "ci"])
.withExec(["npm", "run", "build"])
.withExec(["npm", "test"])
// テスト結果を取得
const result = await runner.stdout()
console.log(result)
// Dockerイメージとしてエクスポート
await runner
.withEntrypoint(["node", "dist/index.js"])
.publish("registry.example.com/my-app:latest")
})
このコードは以下の特徴を持つ。
- ローカルで
dagger run node pipeline.tsで実行可能: CI/CDプラットフォーム不要 - GitHub Actionsでも同じコードを呼び出すだけ:
run: dagger run node pipeline.ts - テスト可能: TypeScriptの通常のテストフレームワークでパイプラインロジックをテスト可能
- 型安全: SDKの型定義により、誤った設定がコンパイル時に検出される
Dagger Functions(Dagger Modules)
Dagger 1.x系で導入されたDagger Functionsは、パイプラインのステップを再利用可能な関数として定義・公開する仕組みだ。
// Go で Dagger Function を定義
package main
import "dagger.io/dagger"
type MyPipeline struct{}
// ビルド関数
func (m *MyPipeline) Build(ctx context.Context, source *dagger.Directory) *dagger.Container {
return dag.Container().
From("golang:1.22").
WithDirectory("/src", source).
WithWorkdir("/src").
WithExec([]string{"go", "build", "-o", "/app", "."})
}
// テスト関数
func (m *MyPipeline) Test(ctx context.Context, source *dagger.Directory) (string, error) {
return m.Build(ctx, source).
WithExec([]string{"go", "test", "./..."}).
Stdout(ctx)
}
Dagger FunctionsはDaggerverse(Dagger版のnpmレジストリ)で公開・共有でき、他のプロジェクトからdagger callで直接呼び出せる。
CI/CDツール比較
以下の図は、主要CI/CDツールをポータビリティとローカル実行可能性で分類しています。
| 項目 | Dagger | GitHub Actions | GitLab CI | Jenkins | Tekton |
|---|---|---|---|---|---|
| パイプライン定義 | Go/Python/TS | YAML | YAML | Groovy | YAML |
| ローカル実行 | ○(完全) | △(actで部分的) | △ | △ | ✗ |
| ポータビリティ | ○(完全) | ✗(GH依存) | ✗(GL依存) | △ | △(K8s依存) |
| テスト可能性 | ○(ユニットテスト) | ✗ | ✗ | △ | ✗ |
| デバッグ | ○(ブレークポイント) | ✗(ログのみ) | ✗(ログのみ) | △ | ✗ |
| キャッシング | ○(BuildKitレイヤー) | ○(actions/cache) | ○ | △ | △ |
| エコシステム | Daggerverse | Actions Marketplace | Templates | プラグイン | Hub |
| 学習コスト | 中(SDK学習) | 低 | 低 | 高 | 高 |
| 料金 | OSS無料 + Cloud有料 | 無料枠あり | 無料枠あり | 無料(自前運用) | 無料(K8s必要) |
GitHub Copilotとの相性
DaggerパイプラインはプログラミングSDKで書くため、GitHub CopilotなどのAIコーディングアシスタントとの相性が非常に良い。YAMLのCI/CD定義ではAI補完の精度が低いが、Go/Python/TypeScriptのDagger SDKコードでは高品質な補完が得られる。
実践:GitHub ActionsからDaggerへの移行
Step 1: 既存のGitHub Actions Workflow
# .github/workflows/ci.yml(移行前)
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build
- run: npm test
- uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/my-org/my-app:latest
Step 2: Daggerパイプラインに変換
// ci/pipeline.ts
import { connect } from "@dagger.io/dagger"
connect(async (client) => {
const source = client.host().directory(".")
const app = client.container()
.from("node:20-slim")
.withDirectory("/app", source)
.withWorkdir("/app")
.withExec(["npm", "ci"])
.withExec(["npm", "run", "build"])
.withExec(["npm", "test"])
// <AffiliateLink id="docker">Docker</AffiliateLink>イメージをビルド&プッシュ
await app
.withEntrypoint(["node", "dist/index.js"])
.publish("ghcr.io/my-org/my-app:latest")
})
Step 3: GitHub Actionsから呼び出し
# .github/workflows/ci.yml(移行後)
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dagger/dagger-for-github@v6
with:
verb: run
args: node ci/pipeline.ts
GitHub ActionsのワークフローはDaggerを呼び出すだけの薄いラッパーになる。パイプラインのロジックはDaggerコード側に集約され、ローカルでもdagger run node ci/pipeline.tsで同じ動作を確認できる。
日本ではどうなるか
採用状況
日本でのDagger採用はまだ初期段階だが、以下の理由で今後の成長が見込まれる。
- Docker Compose文化との親和性: 日本の開発現場ではDocker Composeが広く普及しており、「パイプラインもコンテナで動かす」Daggerのコンセプトは受け入れやすい
- YAML疲れ: GitHub Actions + ArgoCD + Helm + Kustomizeと、YAML定義ファイルの爆発的増加に多くの日本企業が悩んでいる
- ローカルファースト: 「CIに push してみないとわからない」問題は日本の開発者からも頻繁に不満として挙がる
導入障壁
- SDK学習コスト: YAMLに慣れたSREチームにとって、Go/Python/TypeScriptでパイプラインを書くことへの心理的ハードルがある
- 日本語ドキュメントの不足: Daggerのドキュメントは英語のみ
- エンタープライズ導入実績: 日本の大企業での導入事例がまだほとんど公開されていない
コミュニティ
DaggerはDiscordコミュニティが活発で、日本語チャンネルも存在する。Solomon Hykes自身がコミュニティに積極的に参加しており、質問への回答も早い。
まとめ:Dagger導入のアクションステップ
CI/CDの「Write Once, Run Anywhere」を実現するDaggerは、特にマルチCI/CD環境やローカルデバッグに課題を抱えるチームに強く推奨できる。
- ローカルで試す:
brew install daggerでインストールし、既存プロジェクトでdagger initを実行。10分で最初のパイプラインが動く - 最も痛い問題から始める: 「CIでしか再現しないバグ」「CI/CD設定の変更がPRレビューしにくい」など、現在のCI/CDの最大の課題をDaggerで解決する
- 既存CI/CDとの共存: Daggerは既存のGitHub Actions/GitLab CIを置き換えるのではなく、その中から呼び出される。段階的な移行が可能
- Daggerverseの活用: コミュニティが公開しているDagger Functionsを活用し、車輪の再発明を避ける
- チームへの展開: パイプラインが「コード」になることで、コードレビュー、テスト、リファクタリングのプラクティスがCI/CDにも適用できることをチームに共有する
Solomon Hykesがかつてコンテナで「アプリケーションのポータビリティ」を実現したように、Daggerで「CI/CDのポータビリティ」を実現しようとしている。CI/CDの進化を追うエンジニアにとって、Daggerは必ずウォッチすべきプロジェクトだ。
「開発ツール」カテゴリの記事
- 開発ツール
Cursor 3リリース——AIエージェントが開発を自律的にこなす新時代
- 開発ツール
watchOS 26で64bit完全必須化——Apple開発者が今すぐ対応すべきこと
- 開発ツール
Google「Android Developer Verifier」全開発者に展開開始
- 開発ツール
Gemini Code Assistが無料化——月18万回のコード補完でCopilotの90倍
- 開発ツール
Windsurf Wave 13がArena Modeと並列エージェントを搭載——AI IDE戦争が新局面へ
- 開発ツール
React 19のServer Componentsが本番普及——フロントエンド開発の新常識