Quickstart
From zero to a running workflow in under five minutes.
1. Install
curl -fsSL https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.sh | bashirm https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.ps1 | iexdocker pull ghcr.io/dagucloud/dagu:latestnpm install -g --ignore-scripts=false @dagucloud/dagubrew install daguThe script installers run a guided wizard for PATH setup, background service setup, and the first admin account. Homebrew, npm, and Docker install the binary or container only.
Full options (specific versions, custom directories, service scope, uninstall, CI/non-interactive): Installation Guide.
Verify:
dagu version2. Write your first workflow
A DAG is a YAML file. Save the following as hello.yaml:
steps:
- id: hello
run: echo "Hello from Dagu!"
- id: step_2
run: echo "Running step 2"
depends: hello3. Run it
dagu start hello.yamlOutput:
Succeeded - 2026-04-24T15:23:07+09:00
dag: hello (0s)
├─log: .../logs/hello/.../dag-run....log
│
├─cmd_1 (0s) [succeeded]
│ ├─echo "Hello from Dagu!"
│ │
│ └─stdout: .../cmd_1....out
│ Hello from Dagu!
│
└─cmd_2 (0s) [succeeded]
├─echo "Running step 2"
│
└─stdout: .../cmd_2....out
Running step 2
Result: SucceededTimestamp, duration, and log paths vary by run.
Other useful commands:
dagu validate hello.yaml # Check syntax without running
dagu dry hello.yaml # Show execution plan
dagu status hello # Last run status
dagu history hello # Recent runsRun with Docker instead:
mkdir -p ~/.dagu/dags && cp hello.yaml ~/.dagu/dags/
docker run --rm -v ~/.dagu:/var/lib/dagu ghcr.io/dagucloud/dagu:latest \
dagu start hello4. Open the web UI
dagu start-allVisit http://localhost:8080. The UI shows live run status, logs per step, execution history, and a YAML editor.
On first launch against an empty DAGs directory (~/.config/dagu/dags/), Dagu creates a set of example workflows (example-01-basic-sequential.yaml through example-06-container-workflow.yaml). Set DAGU_SKIP_EXAMPLES=true or skip_examples: true in config.yaml to disable.
Core pieces
Dependencies
type: graph
steps:
- id: extract
run: ./extract.sh
- id: transform_a
run: ./transform_a.sh
depends: extract
- id: transform_b
run: ./transform_b.sh
depends: extract
- id: load
run: ./load.sh
depends: [transform_a, transform_b]Parameters
params:
- SOURCE: /data
- DEST: /backup
steps:
- run: tar -czf ${DEST}/backup.tar.gz ${SOURCE}dagu start backup.yaml -- SOURCE=/important DEST=/backupsRetries and error handling
steps:
- id: download
run: curl -f https://example.com/data.zip -o data.zip
retry_policy:
limit: 3
interval_sec: 30
- id: process
run: ./process.sh data.zip
continue_on:
failure: true
depends: download
handler_on:
failure:
run: echo "run failed" | mail -s "alert" admin@example.com
exit:
run: rm -f data.zip
depends: downloadContainers
Run every step in the same container:
container:
image: python:3.11
volumes:
- ./data:/data
steps:
- id: write_file
run: python -c "open('/data/out.txt','w').write('hi')"
- id: read_file
run: python -c "print(open('/data/out.txt').read())"
depends: write_fileOr run a single step in its own container:
steps:
- name: build
container:
image: node:20-alpine
run: npm run buildScheduling
schedule: "0 2 * * *" # 2 AM daily
overlap_policy: skip # drop new runs while one is active
timeout_sec: 3600
steps:
- run: ./nightly.shWorking directory
DAGs execute in the directory of the YAML file by default. Override with working_dir:
working_dir: /app/project
dotenv: .env # resolved from working_dir
steps:
- run: ls -laNext steps
- Core Concepts — steps, dependencies, execution model
- Deployment Models — local, self-hosted, managed, and hybrid options
- Writing Workflows — full YAML surface
- Step Types — built-in executors (docker, ssh, http, wait, sql, s3, sub-DAG, ...)
- Examples — ready-to-adapt patterns
- CLI Reference — every command and flag
- AI Agent — built-in AI agent and the Dagu skill for external AI tools
- MCP Server — connect MCP-capable clients to a running Dagu server
