Dagu is a self-contained, lightweight workflow engine for enterprise and small teams. Define workflows in simple YAML, execute them anywhere with a single binary, compose complex pipelines from reusable sub-workflows, and distribute tasks across workers. All without requiring databases, message brokers, or code changes to your existing scripts.
Built for developers who want powerful workflow orchestration without the operational overhead. For a quick feel of how it works, take a look at the examples.
Single binary. No database, no message broker. Deploy anywhere in secondsβfrom your laptop to bare metal servers to Kubernetes. Everything is stored in plain files (XDG compliant), making it transparent, portable, and easy to backup.
Build complex pipelines from reusable building blocks. Define sub-workflows that can be called with parameters, executed in parallel, and fully monitored in the UI. See execution traces for every nested levelβno black boxes.
Use your existing scripts without modification. No need to wrap everything in Python decorators or rewrite logic. Dagu orchestrates shell commands, Docker containers, SSH commands, or HTTP callsβwhatever you already have.
Built-in queue system with intelligent task routing. Route tasks to workers based on labels (GPU, region, compliance requirements). Automatic service registry and health monitoring includedβno external coordination service needed.
Not a toy. Battle-tested error handling with exponential backoff retries, lifecycle hooks (onSuccess, onFailure, onExit), real-time log streaming, email notifications, Prometheus metrics, and OpenTelemetry tracing out of the box. Built-in user management with role-based access control (RBAC) for team environments.
Beautiful UI that actually helps you debug. Live log tailing, DAG visualization with Gantt charts, execution history with full lineage, and drill-down into nested sub-workflows. Dark mode included.
macOS/Linux:
# Install to ~/.local/bin (default, no sudo required)
curl -L https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.sh | bash
# Install specific version
curl -L https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.sh | bash -s -- --version v1.17.0
# Install to custom directory
curl -L https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.sh | bash -s -- --install-dir /usr/local/bin
# Install to custom directory with custom working directory
curl -L https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.sh | bash -s -- --install-dir /usr/local/bin --working-dir /var/tmpWindows (PowerShell):
# Install latest version to default location (%LOCALAPPDATA%\Programs\dagu)
irm https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.ps1 | iex
# Install specific version
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.ps1))) v1.24.0
# Install to custom directory
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.ps1))) latest "C:\tools\dagu"Windows (CMD/PowerShell):
REM Install latest version to default location (%LOCALAPPDATA%\Programs\dagu)
curl -fsSL https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.cmd -o installer.cmd && .\installer.cmd && del installer.cmd
REM Install specific version
curl -fsSL https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.cmd -o installer.cmd && .\installer.cmd v1.24.0 && del installer.cmd
REM Install to custom directory
curl -fsSL https://raw.githubusercontent.com/dagu-org/dagu/main/scripts/installer.cmd -o installer.cmd && .\installer.cmd latest "C:\tools\dagu" && del installer.cmdDocker:
docker run --rm \
-v ~/.dagu:/var/lib/dagu \
-p 8080:8080 \
ghcr.io/dagu-org/dagu:latest \
dagu start-allNote: see documentation for other methods.
Homebrew:
brew update && brew install dagu
# Upgrade to latest version
brew update && brew upgrade dagunpm:
# Install via npm
npm install -g --ignore-scripts=false @dagu-org/daguNote: When you first start Dagu with an empty DAGs directory, it automatically creates example workflows to help you get started. To skip this, set
DAGU_SKIP_EXAMPLES=true.
cat > ./hello.yaml << 'EOF'
steps:
- echo "Hello from Dagu!"
- echo "Running step 2"
EOFdagu start hello.yamldagu status hellodagu start-allVisit http://localhost:8080
Clone the repository and run with Docker Compose:
git clone https://github.com/dagu-org/dagu.git
cd daguRun with minimal setup:
docker compose -f deploy/docker/compose.minimal.yaml up -d
# Visit http://localhost:8080Stop containers:
docker compose -f deploy/docker/compose.minimal.yaml downYou can also use the production-like configuration deploy/docker/compose.prod.yaml with OpenTelemetry, Prometheus, and Grafana:
docker compose -f deploy/docker/compose.prod.yaml up -d
# Visit UI at http://localhost:8080
# Jaeger at http://localhost:16686, Prometheus at http://localhost:9090, Grafana at http://localhost:3000Note: It's just for demonstration purposes. For production, please customize the configuration as needed.
For Kubernetes deployment, see the example manifests in deploy/k8s/README.md.
- Chat with us by joining our Discord server
- File bug reports and feature requests on our GitHub Issues
- Follow us on Bluesky for updates
For a detailed list of changes, bug fixes, and new features, please refer to the Changelog.
Full documentation is available at docs.dagu.cloud.
Helpful Links:
- Feature by Examples - Explore useful features with examples
- Remote Execution via SSH - Run commands on remote machines using SSH
- Distributed Execution - How to run workflows across multiple machines
- Scheduling - Learn about flexible scheduling options (start, stop, restart) with cron syntax
- Authentication - Configure authentication for the Web UI
- Configuration - Detailed configuration options for customizing Dagu
Note: Configuration precedence: Command-line flags > Environment variables > Configuration file
| Environment Variable | Default | Description |
|---|---|---|
DAGU_HOST |
127.0.0.1 |
Web UI server host |
DAGU_PORT |
8080 |
Web UI server port |
DAGU_BASE_PATH |
- | Base path for reverse proxy setup |
DAGU_API_BASE_URL |
/api/v2 |
API endpoint base path |
DAGU_TZ |
- | Server timezone (e.g., Asia/Tokyo) |
DAGU_DEBUG |
false |
Enable debug mode |
DAGU_LOG_FORMAT |
text |
Log format (text or json) |
DAGU_HEADLESS |
false |
Run without Web UI |
DAGU_LATEST_STATUS_TODAY |
false |
Show only today's latest status |
DAGU_WORK_DIR |
- | Default working directory for DAGs |
DAGU_DEFAULT_SHELL |
- | Default shell for command execution |
DAGU_CERT_FILE |
- | TLS certificate file path |
DAGU_KEY_FILE |
- | TLS key file path |
| Environment Variable | Default | Description |
|---|---|---|
DAGU_HOME |
- | Base directory that overrides all path configurations |
DAGU_DAGS_DIR |
~/.config/dagu/dags |
Directory for DAG definitions |
DAGU_LOG_DIR |
~/.local/share/dagu/logs |
Directory for log files |
DAGU_DATA_DIR |
~/.local/share/dagu/data |
Directory for application data |
DAGU_SUSPEND_FLAGS_DIR |
~/.local/share/dagu/suspend |
Directory for suspend flags |
DAGU_ADMIN_LOG_DIR |
~/.local/share/dagu/logs/admin |
Directory for admin logs |
DAGU_BASE_CONFIG |
~/.config/dagu/base.yaml |
Path to base configuration file |
DAGU_EXECUTABLE |
- | Path to dagu executable |
DAGU_DAG_RUNS_DIR |
{dataDir}/dag-runs |
Directory for DAG run data |
DAGU_PROC_DIR |
{dataDir}/proc |
Directory for process data |
DAGU_QUEUE_DIR |
{dataDir}/queue |
Directory for queue data |
DAGU_SERVICE_REGISTRY_DIR |
{dataDir}/service-registry |
Directory for service registry |
| Environment Variable | Default | Description |
|---|---|---|
DAGU_AUTH_MODE |
- | Authentication mode: none, builtin, or oidc |
DAGU_AUTH_BASIC_USERNAME |
- | Basic auth username |
DAGU_AUTH_BASIC_PASSWORD |
- | Basic auth password |
DAGU_AUTH_OIDC_CLIENT_ID |
- | OIDC client ID |
DAGU_AUTH_OIDC_CLIENT_SECRET |
- | OIDC client secret |
DAGU_AUTH_OIDC_CLIENT_URL |
- | OIDC client URL |
DAGU_AUTH_OIDC_ISSUER |
- | OIDC issuer URL |
DAGU_AUTH_OIDC_SCOPES |
- | OIDC scopes (comma-separated) |
DAGU_AUTH_OIDC_WHITELIST |
- | OIDC email whitelist (comma-separated) |
When DAGU_AUTH_MODE=builtin, a file-based user management system with role-based access control is enabled. Roles: admin, manager, operator, viewer.
| Environment Variable | Default | Description |
|---|---|---|
DAGU_AUTH_ADMIN_USERNAME |
admin |
Initial admin username |
DAGU_AUTH_ADMIN_PASSWORD |
(auto-generated) | Initial admin password |
DAGU_AUTH_TOKEN_SECRET |
- | JWT token secret for signing (required) |
DAGU_AUTH_TOKEN_TTL |
24h |
JWT token time-to-live |
DAGU_USERS_DIR |
{dataDir}/users |
Directory for user data files |
| Environment Variable | Default | Description |
|---|---|---|
DAGU_UI_NAVBAR_COLOR |
#1976d2 |
UI header color (hex or name) |
DAGU_UI_NAVBAR_TITLE |
Dagu |
UI header title |
DAGU_UI_LOG_ENCODING_CHARSET |
utf-8 |
Log file encoding |
DAGU_UI_MAX_DASHBOARD_PAGE_LIMIT |
100 |
Maximum items on dashboard |
DAGU_UI_DAGS_SORT_FIELD |
name |
Default DAGs sort field |
DAGU_UI_DAGS_SORT_ORDER |
asc |
Default DAGs sort order |
| Environment Variable | Default | Description |
|---|---|---|
DAGU_SCHEDULER_PORT |
8090 |
Health check server port |
DAGU_SCHEDULER_LOCK_STALE_THRESHOLD |
30s |
Scheduler lock stale threshold |
DAGU_SCHEDULER_LOCK_RETRY_INTERVAL |
5s |
Lock retry interval |
DAGU_SCHEDULER_ZOMBIE_DETECTION_INTERVAL |
45s |
Zombie DAG detection interval (0 to disable) |
DAGU_QUEUE_ENABLED |
true |
Enable queue system |
This configuration is used for worker instances that execute DAGs. See the Distributed Execution documentation for more details.
| Environment Variable | Default | Description |
|---|---|---|
DAGU_COORDINATOR_HOST |
127.0.0.1 |
Coordinator gRPC server bind address |
DAGU_COORDINATOR_ADVERTISE |
(auto) | Address to advertise in service registry (default: hostname) |
DAGU_COORDINATOR_PORT |
50055 |
Coordinator gRPC server port |
DAGU_WORKER_ID |
- | Worker instance ID |
DAGU_WORKER_MAX_ACTIVE_RUNS |
100 |
Maximum concurrent runs per worker |
DAGU_WORKER_LABELS |
- | Worker labels (format: key1=value1,key2=value2, e.g., gpu=true,memory=64G) |
DAGU_SCHEDULER_PORT |
8090 |
Scheduler health check server port |
DAGU_SCHEDULER_LOCK_STALE_THRESHOLD |
30s |
Time after which scheduler lock is considered stale |
DAGU_SCHEDULER_LOCK_RETRY_INTERVAL |
5s |
Interval between lock acquisition attempts |
This configuration is used for communication between coordinator services and other services (e.g., scheduler, worker, web UI). See the Distributed Execution documentation for more details.
| Environment Variable | Default | Description |
|---|---|---|
DAGU_PEER_CERT_FILE |
- | Peer TLS certificate file |
DAGU_PEER_KEY_FILE |
- | Peer TLS key file |
DAGU_PEER_CLIENT_CA_FILE |
- | Peer CA certificate file for client verification |
DAGU_PEER_SKIP_TLS_VERIFY |
false |
Skip TLS certificate verification for peer connections |
DAGU_PEER_INSECURE |
true |
Use insecure connection (h2c) instead of TLS |
git clone https://github.com/dagu-org/dagu.git && cd dagu
makeThis will start the dagu server at http://localhost:8080.
cd ui
pnpm install
pnpm devNavigate to http://localhost:8081 to view the frontend.
To ensure the integrity of the go code, you can run all Go unit and integration tests.
Run all tests from the project root directory:
make testTo run tests with code coverage analysis:
make make-coverageThis section outlines the current capabilities of Dagu.
| Category | Capability | Description | Link |
|---|---|---|---|
| Core Execution & Lifecycle | Local execution | Run workflows locally with CLI / Web UI / API | CLI, Web UI, API |
| Queue based execution | Dispatch DAG execution to workers with labels and priorities | Queues | |
| Immediate execution | Disable queue for immediate execution | CLI | |
| Idempotency | Prevent duplicate DAG execution with same DAG-run ID | start command |
|
| Status management | queued β running β succeeded/partially_succeeded/failed/aborted | Status Management | |
| Cancel propagation | Cancel signals to sub-DAG | ||
| Cleanup hooks | Define cleanup processing with onExit handlers | Lifecycle Handlers | |
| Status hooks | Define hooks on success / failure / cancel | Lifecycle Handlers | |
| Definition & Templates | Declarative YAML DSL | Validation with JSON Schema, display error locations | YAML Specification |
| Environment variables | Environment variables at DAG and step level, support dotenv | Environment Variables | |
| Command substitution | Use command output as value for variables or parameters | Command Substitution | |
| Shell support | Use shell features like pipes, redirects, globbing, etc. | Shell Executor | |
| Script support | Use scripts in Python, Bash, etc. as steps | Script Execution | |
| Modular DAGs | Reusable DAGs with params | Base Configuration, Parallel Execution | |
| Secrets management | Reference-only secrets via KMS/Vault/OIDC | Secrets | |
| Control Structures | Fan-out/Fan-in | Native parallel branches + join | Parallel Execution |
| Iteration (loop) | Iteration over list values | Parallel Execution | |
| Conditional routes | Data/expression based routing | Conditional Execution | |
| Sub-DAG call | Reusable sub-DAG | Parallel Execution | |
| Worker & Dispatch | Runs DAG on different nodes with selector conditions | Distributed Execution | |
| Retry policies | Retry with backoff/interval | Retry Policies | |
| Repeat Policies | Repeat step until condition is met | Repeat Policies | |
| Timeout management | DAG Execution Timeouts | Workflow Timeout | |
| Triggers & Scheduling | Cron expression | Schedule to start / stop / restart | Scheduling |
| Multiple schedules | Multiple schedules per DAG | Multiple Schedules | |
| Timezone support | Per-DAG timezone for cron schedules | Timezone Support | |
| Skip | Skip an execution when a previous manual run was successful | Skip Redundant Runs | |
| Zombie detection | Automatic detection for processes terminated unexpectedly | Scheduling | |
| Trigger via Web API | Web API to start DAG executions | Web API | |
| Container Native Execution | Step-level container config | Run steps in Docker containers with granular control | Docker Executor |
| DAG level container config | Run all steps in a container with shared volumes and env vars | Container Field | |
| Authorized registry access | Access private registries with credentials | Registry Auth | |
| Data & Artifacts | Passing data between steps | Passing ephemeral data between steps in a DAG | Data Flow |
| Secret redaction | Auto-mask secrets in logs/events | ||
| Automatic log cleanup | Automatic log cleanup based on retention policies | Log Retention | |
| Observability | Logging with live streaming | Structured JSON logs with live tail streaming | Log Viewer |
| Metrics | Prometheus metrics | Metrics | |
| OpenTelemetry | Distributed tracing with OpenTelemetry | OpenTelemetry | |
| DAG Visualization | DAG / Gantt charts for critical path analysis | DAG Visualization | |
| Email notification | Email notification on success / failure with the log file attachment | Email Notifications | |
| Health monitoring | Health check for scheduler & failover | Health Check | |
| Nested-DAG visualization | Nested DAG visualization with drill down functionality | Nested DAG Visualization | |
| Security & Governance | Secret injection | Vault/KMS/OIDC ref-only; short-lived tokens | Secrets |
| Authentication | Basic auth / OIDC / Builtin (JWT) support for Web UI and API | Authentication | |
| Role-based access control | Builtin RBAC with admin, manager, operator, viewer roles | ||
| User management | Create, update, delete users with role assignment | ||
| HA (High availability) mode | Control-plane with failover for scheduler / Web UI / Coordinator | High Availability | |
| Executor types | jq |
JSON processing with jq queries | JQ Executor |
ssh |
Remote command execution via SSH | SSH Executor | |
docker |
Container-based task execution | Docker Executor | |
http |
HTTP/REST API calls with retry | HTTP Executor | |
mail |
Send emails with template | Mail Executor | |
archive |
Archive/unarchive operations (zip, tar, etc.) | Archive Executor | |
| DevX & Testing | Local development | offline runs | CLI Usage |
| Dry-run | DAG level Dry-run | dry command |
|
| UI & Operations | Run / retry / cancel operations | Start / enqueue / retry / stop | DAG Operations |
| Automatic parameter forms | Auto-generate parameter forms for DAGs | Web UI | |
| DAG definition search | Filter by tag / name | DAG Search | |
| Execution history search | Filter by status / date-range / name | History Search | |
| Step-level operations | Rerun, resume from step | Web UI | |
| Parameter override | Override parameters for a DAG run | ||
| Scheduled DAG management | Enable/disable schedule for a DAG | Web UI | |
| UI organization | Logical DAG grouping | DAG Organization | |
| Others | Windows support | Windows support |
This section outlines the planned features for Dagu.
Legend:
- Status: ποΈ In Progress / π Planned / π Designing / β Blocked / π’ Enterprise
- Priority: P0 = Must have / P1 = Should have / P2 = Could have
| Category | Capability | Description | Status | Priority | Link |
|---|---|---|---|---|---|
| Definition & Templates | Variables store | Env-scoped variables | π | P1 | |
| Code-based SDK | Python / Go / TS SDK to build DAG programmatically | π | P2 | #583 | |
| Go template support | Use Go templates in DAG definitions | π | P2 | #738 | |
| Control Structures | Matrix runs | Create all parameter combinations | π | P1 | #879, #990 |
| Human-in-the-loop | Wait for human approval / input | π | P0 | #978 | |
| Triggers & Scheduling | Second-precision cron | Per-DAG TZ, holiday calendar, exclusion windows | π | P2 | #676 |
| Sunset/Sunrise triggers | Trigger DAG on sunrise/sunset events | π | P2 | #1004 | |
| Catch up | Catch up on missed executions with safety caps | π | P0 | #695 | |
| Overlap | Overlap policy (skip/queue/cancel) | π | P1 | ||
| Queue Override | Override queue for specific runs | π | P0 | #1111 | |
| Backfill | Historical range runs with safety caps | π | P2 | #695 | |
| File watcher trigger | Trigger DAG on file changes in a directory | π | P0 | #372 | |
| Holiday calendars | Import & reference holiday calendars | π | P2 | #676 | |
| Container Native Execution | On-the-fly image build | Builds image on-the-fly during DAG execution | π | P0 | |
| Kubernetes native execution | Run steps as Kubernetes jobs/pods | π | P0 | #837 | |
| Resource Management | Resource limits | CPU/Memory/IO requests & limits per-step | π | P0 | |
| Rate limiting | Token bucket per key/endpoint for external APIs | π | P1 | ||
| Distributed locks | Keyed semaphore for exclusivity | π | P0 | ||
| Data & Artifacts | JSON Schema validation | Parameter validation with JSON Schema | π | P0 | #325 |
| External storage | Stream large logs/artifacts to S3/GCS/Azure | π | P2 | #640, #548, #267 | |
| Inter DAG-run state management | Manage state and data sharing between DAG-runs | π | P0 | ||
| Database backend support | Support for external databases (PostgreSQL, MySQL) instead of filesystem | π | P1 | #539, #267 | |
| Observability | Resource usage monitoring | CPU/Memory/IO usage per DAG/step with live graphs | π | P0 | #546 |
| Security & Governance | Fine-grained permissions | DAG-level and resource-level permissions | π’ | ||
| Resource quotas | CPU time and memory limit | π | P0 | ||
| Audit trail | Immutable events for all manual actions | π’ | |||
| Audit logging | Immutable who/what/when records (WORM) | π’ | |||
| Executor types | database |
Direct database read/write operations | π | P2 | #789 |
ftp |
File transfer protocol support | π | P2 | #1079 | |
| Custom plugin system | Custom executor types | π | P1 | #583 | |
| DevX & Testing | Debug mode | debug mode for step-by-step DAG execution | π | P1 | #1119 |
| Static analysis | DAG Validation tool | π | P0 | #325 | |
| Migration helpers | Provide migration helpers from cron-only DAGs to full scheduler | π | P1 | #448 | |
| UI & Operations | Pause / resume operations | Pause / resume DAG executions | π | P0 | |
| Run single step | Run a single step in a DAG | π | P0 | #1047 | |
| Edit & retry | Edit DAG definition before retrying a run | π | P0 | #326, #1058 | |
| Version control | Diff/compare/rollback DAG definitions | π | P2 | #320, #374 | |
| Others | Snap packaging | Snap packaging | π | P1 | #821, #871 |
For discussions, support, and sharing ideas, join our community on Discord.
Changelog of recent updates can be found in the Changelog section of the documentation.
We welcome contributions of all kinds! Whether you're a developer, a designer, or a user, your help is valued. Here are a few ways to get involved:
- Star the project on GitHub.
- Suggest new features by opening an issue.
- Join the discussion on our Discord server.
- Contribute code: Check out our issues you can help with.
For more details, see our Contribution Guide.
Thanks to all the contributors who have helped make Dagu better! Your contributions, whether through code, documentation, or feedback, are invaluable to the project.
Thanks for supporting Daguβs development! Join our supporters: GitHub Sponsors
GNU GPLv3 - See LICENSE






