1. บทนำ: Dagger คืออะไร?
Dagger เป็น programmable CI/CD engine ที่ช่วยให้คุณเขียน pipeline เป็น code ด้วยภาษาโปรแกรมจริง (เช่น Go, Python, TypeScript) แทนที่จะใช้ YAML configuration files ที่มักซับซ้อนและยากต่อการจัดการ
Dagger ถูกสร้างโดยทีมผู้สร้าง Docker (Solomon Hykes) และออกแบบมาเพื่อแก้ปัญหาหลักของ CI/CD แบบดั้งเดิม:
- "Works on my machine" problem: Pipeline ที่ทำงานบน local ไม่เหมือนกับบน CI server
- YAML complexity: YAML files ที่ขยายใหญ่ขึ้นและยากต่อการอ่าน/แก้ไข
- Vendor lock-in: Pipeline ที่ผูกติดกับ CI provider เฉพาะ
- Slow feedback loop: ต้อง push code ไปที่ remote repository ทุกครั้งเพื่อทดสอบ pipeline
ด้วย Dagger คุณสามารถเขียน pipeline ครั้งเดียวแล้วรันได้ทั้งบน local machine และ CI/CD platform ใดก็ได้ (GitHub Actions, GitLab CI, Jenkins, etc.) โดยใช้ container เป็น execution environment
Programmable Pipelines
เขียน pipeline ด้วยภาษาโปรแกรมจริง ใช้ condition, loop, function reuse ได้เต็มที่
Local & CI Parity
Pipeline เดียวกันรันได้ทั้งบน local machine และ CI server ผลลัพธ์เหมือนกัน
2. สิ่งที่ต้องเตรียม
ก่อนเริ่มใช้งาน Dagger คุณต้องมีสิ่งต่อไปนี้:
พื้นฐานภาษาโปรแกรม
Go, Python, หรือ TypeScript พื้นฐาน (เลือกอย่างน้อย 1 ภาษา)
Docker หรือ Container Runtime
Docker Desktop, Podman, หรือ container runtime อื่นๆ
ระบบปฏิบัติการ
Linux, macOS, หรือ Windows (WSL2 สำหรับ Windows)
ความรู้ CI/CD พื้นฐาน
เข้าใจ concept ของ CI/CD pipelines และ workflow พื้นฐาน
ระดับความยาก: Intermediate
บทความนี้เหมาะสำหรับผู้ที่มีพื้นฐาน DevOps/CI/CD มาบ้างแล้ว ถ้าคุณเพิ่งเริ่มต้นแนะนำให้ศึกษา GitLab CI/CD Fundamentals ก่อน
3. คุณสมบัติเด่นของ Dagger
Core Features
Programmable Pipelines
เขียน pipeline ด้วยภาษาโปรแกรมจริง แทนที่จะใช้ YAML ที่มีข้อจำกัด สามารถใช้ condition, loop, functions, และ abstraction ได้เต็มที่
if os == "linux":
build_linux()
elif os == "windows":
build_windows()
else:
build_macos()
Container-Native Execution
ทุก step ใน pipeline ทำงานใน container ที่แยกจากกัน ใช้ Docker/OCI containers เป็น execution environment ทำให้ได้ผลลัพธ์ที่สม่ำเสมอไม่ว่าคุณจะรันที่ไหน
Built-in Caching
Dagger ใช้ BuildKit เป็น engine ด้านล่าง ทำให้มี caching อัตโนมัติสำหรับทุกขั้นตอน ลดเวลา build ซ้ำได้มากถึง 90%
Composable & Reusable
สามารถสร้าง modules และ functions ที่ reuse กันได้ across projects สร้าง library ของ pipeline components สำหรับองค์กร
Architecture ของ Dagger
รูปแสดง architecture ของ Dagger: Developer เขียน code → Dagger CLI → Dagger Engine (BuildKit) → Containerized execution
4. เปรียบเทียบ: YAML-based vs Dagger (Code-based)
| หัวข้อ | Traditional YAML CI/CD | Dagger (Code-based) |
|---|---|---|
| ภาษา | YAML/DSL (จำกัด) | Go, Python, TypeScript (เต็มที่) |
| Local Testing | ยาก หรือต้องใช้ tools พิเศษ | รัน local ได้เหมือนกับ CI |
| Reusability | Copy-paste หรือ templates | Functions, modules, packages |
| Debugging | ยาก ต้องดู logs บน CI | Debug ด้วย IDE ได้ local |
| Vendor Lock-in | สูง (GitHub Actions, GitLab CI) | ต่ำ (รันได้ทุกที่ที่มี container) |
| Learning Curve | ง่ายเริ่มต้น แต่ซับซ้อนเมื่อใหญ่ | เริ่มต้นยากกว่า แต่ scalable ดี |
Workflow Comparison
5. การติดตั้ง Dagger
การติดตั้ง Dagger ทำได้หลายวิธี ขึ้นอยู่กับระบบปฏิบัติการและความต้องการของคุณ
วิธีที่ 1: ติดตั้งบน Ubuntu/Debian
# Download และติดตั้ง Dagger CLI
curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.14.0 sh
# เพิ่มไปที่ PATH
sudo mv ./dagger /usr/local/bin/
# ตรวจสอบการติดตั้ง
dagger version
วิธีที่ 2: ใช้ Docker (ไม่ต้องติดตั้ง)
# รัน Dagger ผ่าน Docker container
docker run --rm -v $(pwd):/work -w /work \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/dagger/dagger:latest \
dagger version
วิธีที่ 3: ติดตั้งผ่าน Package Manager
Homebrew (macOS)
brew install dagger/tap/dagger
Scoop (Windows)
scoop bucket add dagger
scoop install dagger
ตรวจสอบการติดตั้ง
$ dagger version
dagger 0.14.0 (v0.14.0)
buildkit v0.15.0
$ dagger --help
Usage: dagger <command>
Available Commands:
call Call a function in a module
config Manage dagger configuration
develop Start a development session
func Manage functions
init Initialize a new Dagger module
login Log in to Dagger Cloud
project Manage projects
run Run a Dagger pipeline
shell Open a shell in a service container
version Print Dagger version
6. Tutorial: สร้าง Pipeline แรกของคุณ
ในส่วนนี้เราจะสร้าง simple pipeline สำหรับ build และ test Node.js application
Step 1: Initialize Dagger Project
# สร้าง directory สำหรับ project
mkdir my-dagger-project
cd my-dagger-project
# Initialize Dagger project (เลือกภาษา)
dagger init --sdk=python
# หรือ
dagger init --sdk=go
# หรือ
dagger init --sdk=typescript
Step 2: เขียน Pipeline (Python Example)
import dagger
from dagger import dag, function, object_type
@object_type
class MyApp:
@function
async def build(self, source: dagger.Directory) -> dagger.Directory:
"""Build Node.js application"""
return await (
dag.container()
.from_("node:18-alpine")
.with_directory("/src", source)
.with_workdir("/src")
.with_exec(["npm", "ci"])
.with_exec(["npm", "run", "build"])
.directory("/src/dist")
)
@function
async def test(self, source: dagger.Directory) -> str:
"""Run tests"""
return await (
dag.container()
.from_("node:18-alpine")
.with_directory("/src", source)
.with_workdir("/src")
.with_exec(["npm", "ci"])
.with_exec(["npm", "test"])
.stdout()
)
@function
async def docker_image(self, source: dagger.Directory, tag: str = "latest") -> str:
"""Build Docker image"""
build_dir = await self.build(source)
return await (
dag.container()
.from_("nginx:alpine")
.with_directory("/usr/share/nginx/html", build_dir)
.publish(f"myapp:{tag}")
)
Step 3: รัน Pipeline Locally
# รัน build function
dagger call build --source=. --progress=plain
# รัน test function
dagger call test --source=.
# Build Docker image
dagger call docker-image --source=. --tag=v1.0.0
Step 4: ตัวอย่างเพิ่มเติม (Go & TypeScript)
Go Example
package main
import (
"context"
"dagger.io/dagger"
)
func main() {
ctx := context.Background()
client, err := dagger.Connect(ctx)
if err != nil { panic(err) }
defer client.Close()
source := client.Host().Directory(".")
node := client.Container().
From("node:18").
WithDirectory("/src", source).
WithWorkdir("/src")
build := node.WithExec([]string{"npm", "run", "build"})
output := build.Directory("./dist")
_, err = output.Export(ctx, "./dist")
if err != nil { panic(err) }
}
TypeScript Example
import { connect, Container } from "@dagger.io/dagger";
async function main() {
const client = await connect();
const source = client.host().directory(".");
const node = client.container()
.from("node:18")
.withDirectory("/src", source)
.withWorkdir("/src");
const build = node.withExec(["npm", "run", "build"]);
const output = build.directory("./dist");
await output.export("./dist");
await client.close();
}
main();
7. การใช้งาน Dagger ในบริบทไทย
สำหรับทีมพัฒนาและบริษัทเทคโนโลยีในประเทศไทย Dagger สามารถช่วยแก้ปัญหาหลายอย่างที่พบเจอในการทำ CI/CD
💡 ประโยชน์สำหรับทีมไทย
ลดค่าใช้จ่าย CI/CD
ทีมขนาดเล็กในไทยสามารถรัน pipeline บน local ก่อน push ลดจำนวน build ที่ต้องรันบน CI platform ที่คิดเงินตาม minutes
เพิ่ม Productivity ของ Developer
Developer ไทยสามารถ debug pipeline ได้บนเครื่องตัวเอง ไม่ต้องรอ CI queue หรือเสียเวลา push-pray-debug cycle
เหมาะกับ Internet ในไทย
การรัน pipeline local ช่วยลดปัญหาความเร็วอินเทอร์เน็ต โดยเฉพาะเมื่อต้อง download dependencies ขนาดใหญ่หลายครั้ง
🏢 Use Cases สำหรับบริษัทไทย
Startup / SME
- ลด dependency บน CI providers ราคาแพง
- Developer คนเดียวดูแลหลาย project ได้ง่ายขึ้น
- สร้าง reusable pipeline components สำหรับทีม
Enterprise / Banking
- Security: ควบคุม dependencies และ images กลาง
- Compliance: Audit pipeline code ได้ง่าย
- Standardization: ใช้ pipeline templates มาตรฐาน
📊 ตัวอย่างจริง: Thai Tech Company
บริษัท FinTech ไทย ใช้ Dagger เพื่อจัดการ CI/CD pipeline สำหรับ microservices 20+ services:
- ก่อนใช้ Dagger: แต่ละ service มี GitHub Actions workflow file แยกกัน รวมแล้วกว่า 2,000 บรรทัดของ YAML
- หลังใช้ Dagger: สร้าง shared Dagger module กลาง ใช้โดยทุก services ลด code ซ้ำซ้อน 80%
- ผลลัพธ์: Developer สามารถรัน pipeline ทุก service บน local ได้ ลด CI build time จาก 30 นาทีเหลือ 5 นาที
- Cost savings: ลด CI cost ลง 60% เพราะรันเฉพาะเมื่อจำเป็นจริงๆ
8. Integration กับ Tools อื่นๆ
Dagger ทำงานร่วมกับ CI/CD platforms และ tools อื่นๆ ได้อย่างดี
GitHub Actions
# .github/workflows/dagger.yml
name: Dagger Pipeline
on: [push]
jobs:
dagger:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dagger/dagger-for-github@v4
with:
version: 0.14.0
- run: dagger call build
- run: dagger call test
GitLab CI
# .gitlab-ci.yml
image: docker:latest
services:
- docker:dind
stages:
- dagger
dagger:
stage: dagger
script:
- apk add curl
- curl -L https://dl.dagger.io/dagger/install.sh | sh
- ./dagger version
- ./dagger call build
- ./dagger call test
Jenkins
// Jenkinsfile
pipeline {
agent { docker { image 'docker:latest' } }
stages {
stage('Dagger') {
steps {
sh '''
curl -L https://dl.dagger.io/dagger/install.sh | sh
./dagger call build
./dagger call test
'''
}
}
}
}
Daggerverse: Ecosystem ของ Modules
Daggerverse เป็น registry สำหรับ Dagger modules ที่ community สร้างขึ้น คุณสามารถค้นหาและใช้งาน modules สำเร็จรูปได้:
Popular Dagger Modules
Node.js Builder
Build, test, package Node.js apps
Python Package
Build Python wheels and packages
Docker Multi-arch
Build multi-architecture Docker images
Kubernetes Deploy
Deploy to Kubernetes clusters
9. Best Practices & Troubleshooting
✅ Best Practices สำหรับการใช้ Dagger
1. เริ่มจาก Simple Pipeline
เริ่มจาก pipeline ง่ายๆ ก่อน เช่น build และ test เท่านั้น ค่อยๆ เพิ่ม complexity ตามความต้องการ
2. ใช้ Caching ให้เกิดประโยชน์
Dagger มี built-in caching ผ่าน BuildKit ตรวจสอบว่าคุณใช้ directory และ file caching ถูกต้อง
# ใช้ directory caching สำหรับ dependencies
.with_mounted_cache("/src/node_modules",
dag.cache_volume("node-modules"))
3. สร้าง Reusable Modules
แยก logic ที่ใช้บ่อยๆ ออกเป็น modules และ functions เพื่อ reuse ระหว่าง projects
4. ใช้ Environment Variables สำหรับ Secrets
อย่า hardcode secrets ใน code ใช้ Dagger's secret management หรือ environment variables
# ใช้ secrets
.with_secret_variable("DOCKER_PASSWORD",
dag.set_secret("docker-pass", "..."))
5. Test Pipeline Locally ก่อน Push
ใช้ `dagger call` ทดสอบ pipeline บน local machine ให้แน่ใจว่าทำงานก่อน push ไปยัง CI
🔧 Troubleshooting ปัญหาที่พบบ่อย
Error: "docker daemon not running"
Dagger ต้องการ Docker daemon (หรือ container runtime) ตรวจสอบว่า Docker ทำงานอยู่:
# ตรวจสอบ Docker
docker ps
# หากไม่ได้ ให้ start Docker
sudo systemctl start docker
Error: "buildkitd not running"
Dagger ใช้ BuildKit เป็น engine อาจต้อง start buildkitd ก่อน:
# Start buildkitd
docker run -d --name buildkitd --privileged \
moby/buildkit:latest
# หรือให้ Dagger จัดการเอง (recommended)
export DAGGER_HOST=docker-container://buildkitd
Performance: Build ช้า
ตรวจสอบว่าคุณใช้ caching ถูกต้อง และพิจารณาใช้ Dagger Cloud สำหรับ remote caching
Debugging: ดู Logs
ใช้ `--progress=plain` เพื่อดู detailed logs:
dagger call build --progress=plain
10. คำถามที่พบบ่อย (FAQ)
Dagger แทนที่ CI/CD tools อื่นๆ ได้ไหม?
Dagger ไม่ได้ replace CI/CD platforms (เช่น GitHub Actions, GitLab CI) แต่ทำงานร่วมกันได้ Dagger ช่วยให้คุณเขียน pipeline logic ที่ portable ระหว่าง CI platforms ต่าง ๆ
ต้องเรียนรู้ภาษาโปรแกรมใหม่ไหม?
คุณสามารถเลือกภาษาโปรแกรมที่คุณถนัดจาก Go, Python, หรือ TypeScript ไม่จำเป็นต้องเรียนรู้ทั้งสามภาษา
Dagger ใช้กับ Kubernetes ได้ไหม?
ได้ Dagger มี modules สำหรับ deploy ไปยัง Kubernetes และสามารถรันบน Kubernetes cluster ได้ (ใช้ Dagger Engine ใน container)
Dagger ฟรีหรือมีค่าใช้จ่าย?
Dagger core engine เปิด source ฟรี Dagger Cloud (remote caching, analytics) มีทั้งฟรีและ paid plans
Team ในไทยมีคนใช้ Dagger ไหม?
ยังมีผู้ใช้ไม่มากในไทย แต่กำลังเติบโต ส่วนใหญ่เป็น tech startups และ teams ที่ทำงานกับ multinational companies คุณสามารถ join Dagger community บน Discord หรือ GitHub
เมื่อไหร่ควรใช้ Dagger vs YAML?
ใช้ Dagger เมื่อ: มี pipeline ซับซ้อน, ต้องการรัน local, มีหลาย projects ที่แชร์ logic, ต้องการลด vendor lock-in ใช้ YAML เมื่อ: pipeline ง่ายๆ, ทีมไม่คุ้นกับ programming, ใช้กับ CI platform เฉพาะที่รองรับดีอยู่แล้ว
11. สรุปและขั้นตอนต่อไป
Dagger เป็นเครื่องมือที่มีแนวคิดใหม่สำหรับการทำ CI/CD โดยเปลี่ยนจากการเขียน YAML configuration เป็นการเขียน pipeline logic ด้วยภาษาโปรแกรมจริง ซึ่งให้ประโยชน์หลายด้านสำหรับทีมพัฒนา
🎯 Key Takeaways
- Programmable pipelines: เขียน CI/CD logic ด้วย Go, Python, หรือ TypeScript แทน YAML
- Local & CI parity: รัน pipeline เดียวกันได้ทั้งบน local และ CI server
- Container-native: ใช้ container เป็น execution environment สำหรับแต่ละ step
- Portable: Pipeline ทำงานได้กับทุก CI platform ที่รัน container ได้
- Composable: สร้าง reusable modules และ functions สำหรับองค์กร
🚀 ต่อไปทำอะไร?
สำหรับผู้เริ่มต้น
- ติดตั้ง Dagger และลองรัน quickstart example
- แปลง pipeline YAML เดิมเป็น Dagger code
- ทดลองสร้าง simple build-test pipeline
สำหรับทีม/องค์กร
- ประเมิน pipeline ที่ซับซ้อนที่สุดสำหรับ migration
- สร้าง shared Dagger modules สำหรับทีม
- Integrate กับ CI platform ที่ใช้อยู่
ลองติดตั้ง Dagger วันนี้และเริ่มแปลง pipeline แรกของคุณจาก YAML เป็น code ลดความซับซ้อน เพิ่ม productivity และทำให้ CI/CD workflow ดีขึ้น