πŸ“š Dagu - Awesome Go Library for Workflow Frameworks

Go Gopher mascot for Dagu

No-code workflow executor. it executes DAGs defined in a simple YAML format

🏷️ Workflow Frameworks
πŸ“‚ Workflow Frameworks
⭐ 0 stars
View on GitHub πŸ”—

Detailed Description of Dagu

Zero-invasive Lightweight Workflow Orchestration Engine

Dagu is a workflow orchestration engine that runs as a single binary with no external dependencies. Workflows are defined as DAGs (Directed Acyclic Graphs) in YAML. It supports local execution, cron scheduling, queue-based concurrency control, and distributed coordinator/worker execution across multiple machines over gRPC.

It requires no external databases, no message brokers, and no language-specific runtimes. All state is stored in local files by default.

For a quick look at how workflows are defined, see the examples.

Demo
Cockpit (Kanban)DAG Run Details
CockpitDAG Run Details

Try it live: Live Demo (credentials: demouser / demouser)

Use Cases

Data pipeline orchestration. Define ETL/ELT workflows as DAGs with parallel and sequential steps. Use the built-in SQL executor to query PostgreSQL or SQLite, the S3 executor to move files to/from object storage, the jq executor for JSON transformation, and sub-DAG composition to break large pipelines into reusable stages. Steps can pass outputs to downstream steps.

Infrastructure automation. Run commands on remote machines via the SSH executor with key-based authentication. Execute containers via the Docker or Kubernetes executor. Automate file archiving, deployment scripts, and maintenance tasks. Use preconditions to gate steps on environment checks, and lifecycle hooks (onSuccess, onFailure, onExit) to handle cleanup or notifications.

Scheduled job management. Replace fragile crontab setups with DAGs that have cron scheduling, timezone support, retry policies, overlap control (skip, all, latest), and a web UI showing execution history, logs, and real-time status. Zombie detection automatically identifies and handles stalled runs.

Batch processing. Run compute-heavy workloads across a pool of workers using the coordinator/worker architecture. Workers connect to a coordinator over gRPC, pull tasks from a queue, and report status back. Workers support label-based routing (e.g., gpu=true) so DAGs can target specific machine capabilities.

Legacy script orchestration. Wrap existing shell scripts, Python scripts, HTTP calls, or any executable into workflow steps without modifying them. Dagu orchestrates execution order, captures stdout/stderr, and handles retries and error propagation around your existing code.

Architecture

Dagu can run in three configurations:

Standalone β€” A single dagu start-all process runs the HTTP server, scheduler, and executor. Suitable for single-machine deployments.

Coordinator/Worker β€” The scheduler enqueues jobs to a local file-based queue, then dispatches them to a coordinator over gRPC. Workers long-poll the coordinator for tasks, execute DAGs locally, and report status back. Workers can run on separate machines and are routed tasks based on labels.

Headless β€” Run without the web UI (DAGU_HEADLESS=true). Useful for CI/CD environments or when Dagu is managed through the CLI or API only.

Standalone:

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  dagu start-all                         β”‚
  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
  β”‚  β”‚ HTTP / UI β”‚ β”‚ Scheduler β”‚ β”‚Executorβ”‚ β”‚
  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
  β”‚  File-based storage (logs, state, queue)β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Distributed:

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Scheduler  β”‚                   β”‚ HTTP / UI  β”‚
  β”‚            β”‚                   β”‚            β”‚
  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”‚                   β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
  β”‚ β”‚ Queue  β”‚ β”‚  Dispatch (gRPC)        β”‚ Dispatch / GetWorkers
  β”‚ β”‚(file)  β”‚ │─────────┐               β”‚ (gRPC)
  β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚         β”‚               β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β–Ό               β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚      Coordinator        β”‚
                    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
                    β”‚  β”‚ Dispatch Task     β”‚  β”‚
                    β”‚  β”‚ Store (pending/   β”‚  β”‚
                    β”‚  β”‚ claimed)          β”‚  β”‚
                    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                   Poll (gRPC long-polling)
                             β”‚
               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
               β”‚             β”‚             β”‚
          β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”
          β”‚Worker 1β”‚    β”‚Worker 2β”‚    β”‚Worker Nβ”‚ Sandbox execution of DAGs
          β”‚        β”‚    β”‚        β”‚    β”‚        β”‚
          β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜
               β”‚             β”‚             β”‚
               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 Heartbeat / ReportStatus /
                 StreamLogs (gRPC)

Quick Start

Install

macOS/Linux:

curl -fsSL https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.sh | bash

Homebrew:

brew install dagu

Windows (PowerShell):

irm https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.ps1 | iex

Docker:

docker run --rm -v ~/.dagu:/var/lib/dagu -p 8080:8080 ghcr.io/dagucloud/dagu:latest dagu start-all

Kubernetes (Helm):

helm repo add dagu https://dagucloud.github.io/dagu
helm repo update
helm install dagu dagu/dagu --set persistence.storageClass=<your-rwx-storage-class>

Replace <your-rwx-storage-class> with a StorageClass that supports ReadWriteMany. See charts/dagu/README.md for chart configuration.

The script installers run a guided wizard that can add Dagu to your PATH, set it up as a background service, and create the initial admin account. Homebrew, npm, Docker, and Helm install without the wizard. See Installation docs for all options.

Create and run a workflow

cat > ./hello.yaml << 'EOF'
steps:
  - echo "Hello from Dagu!"
  - echo "Running step 2"
EOF

dagu start hello.yaml

Start the server

dagu start-all

Visit http://localhost:8080

Workflow Examples

Sequential execution

type: chain
steps:
  - command: echo "Step 1"
  - command: echo "Step 2"

Parallel execution with dependencies

type: graph
steps:
  - id: extract
    command: ./extract.sh
  - id: transform_a
    command: ./transform_a.sh
    depends: [extract]
  - id: transform_b
    command: ./transform_b.sh
    depends: [extract]
  - id: load
    command: ./load.sh
    depends: [transform_a, transform_b]
%%{init: {'theme': 'base', 'themeVariables': {'background': '#18181B', 'primaryTextColor': '#fff', 'lineColor': '#888'}}}%%
graph LR
    A[extract] --> B[transform_a]
    A --> C[transform_b]
    B --> D[load]
    C --> D
    style A fill:#18181B,stroke:#22C55E,stroke-width:1.6px,color:#fff
    style B fill:#18181B,stroke:#22C55E,stroke-width:1.6px,color:#fff
    style C fill:#18181B,stroke:#22C55E,stroke-width:1.6px,color:#fff
    style D fill:#18181B,stroke:#3B82F6,stroke-width:1.6px,color:#fff

Docker step

steps:
  - name: build
    container:
      image: node:20-alpine
    command: npm run build

Kubernetes Pod execution

steps:
  - name: batch-job
    type: kubernetes
    config:
      namespace: production
      image: my-registry/batch-processor:latest
      resources:
        requests:
          cpu: "2"
          memory: "4Gi"
    command: ./process.sh

SSH remote execution

steps:
  - name: deploy
    type: ssh
    config:
      host: prod-server.example.com
      user: deploy
      key: ~/.ssh/id_rsa
    command: cd /var/www && git pull && systemctl restart app

Sub-DAG composition

steps:
  - name: extract
    call: etl/extract
    params: "SOURCE=s3://bucket/data.csv"
  - name: transform
    call: etl/transform
    params: "INPUT=${extract.outputs.result}"
    depends: [extract]
  - name: load
    call: etl/load
    params: "DATA=${transform.outputs.result}"
    depends: [transform]

Retry and error handling

steps:
  - name: flaky-api-call
    command: curl -f https://api.example.com/data
    retryPolicy:
      limit: 3
      intervalSec: 10
    continueOn:
      failure: true

Scheduling with overlap control

schedule:
  - "0 */6 * * *"              # Every 6 hours
overlapPolicy: skip             # Skip if previous run is still active
timeoutSec: 3600
handlerOn:
  failure:
    command: notify-team.sh
  exit:
    command: cleanup.sh

For more examples, see the Examples documentation.

Built-in Executors

Dagu includes 17 built-in step executors. Each runs within the Dagu process (or worker) β€” no plugins or external runtimes required.

ExecutorPurpose
commandShell commands and scripts (bash, sh, PowerShell, custom shells)
dockerRun containers with registry auth, volume mounts, resource limits
kubernetesExecute Kubernetes Pods with resource requests, service accounts, namespaces
sshRemote command execution with key-based auth and SFTP file transfer
httpHTTP requests (GET, POST, PUT, DELETE) with headers and authentication
sqlQuery PostgreSQL and SQLite with parameterized queries and result capture
redisRedis commands, pipelines, and Lua scripts
s3Upload, download, list, and delete S3 objects
jqJSON transformation using jq expressions
mailSend email via SMTP
archiveCreate zip/tar archives with glob patterns
dagInvoke another DAG as a sub-workflow with parameter passing
routerConditional step routing based on expressions
templateText generation with template rendering
chatLLM inference (OpenAI, Anthropic, Google Gemini, OpenRouter)
agentstepMulti-step LLM agent execution with tool calling
ghaGitHub Actions execution

See step type documentation for configuration details of each executor.

Security and Access Control

Authentication

Dagu supports four authentication modes, configured via DAGU_AUTH_MODE:

  • none β€” No authentication
  • basic β€” HTTP Basic authentication
  • builtin β€” JWT-based authentication with user management, API keys, and per-DAG webhook tokens
  • OIDC β€” OpenID Connect integration with any compliant identity provider

Role-Based Access Control

When using builtin auth, five roles control access:

RoleCapabilities
adminFull access including user management
managerCreate, edit, delete, run, stop DAGs; view audit logs
developerCreate, edit, delete, run, stop DAGs
operatorRun and stop DAGs only (no editing)
viewerRead-only access

API keys can be created with independent role assignments. Audit logging tracks all actions.

TLS and Secrets

  • TLS for the HTTP server (DAGU_CERT_FILE, DAGU_KEY_FILE)
  • Mutual TLS for gRPC coordinator/worker communication (DAGU_PEER_CERT_FILE, DAGU_PEER_KEY_FILE, DAGU_PEER_CLIENT_CA_FILE)
  • Secret management with three providers: environment variables, files, and HashiCorp Vault

Observability

Prometheus Metrics

Dagu exposes Prometheus-compatible metrics:

  • dagu_info β€” Build information (version, Go version)
  • dagu_uptime_seconds β€” Server uptime
  • dagu_dag_runs_total β€” Total DAG runs by status
  • dagu_dag_runs_total_by_dag β€” Per-DAG run counts
  • dagu_dag_run_duration_seconds β€” Histogram of run durations
  • dagu_dag_runs_currently_running β€” Active DAG runs
  • dagu_dag_runs_queued_total β€” Queued runs

Structured Logging

JSON or text format logging (DAGU_LOG_FORMAT). Logs are stored per-run with separate stdout/stderr capture per step.

Notifications

  • Slack and Telegram bot integration for run monitoring and status updates
  • Email notifications on DAG success, failure, or wait status via SMTP
  • Per-DAG webhook endpoints with token authentication

Scheduling and Reliability

  • Cron scheduling with timezone support and multiple schedule entries per DAG
  • Overlap policies: skip (default β€” skip if previous run is still active), all (queue all), latest (keep only the most recent)
  • Catch-up scheduling: Automatically runs missed intervals when the scheduler was down
  • Zombie detection: Identifies and handles stalled DAG runs (configurable interval, default 45s)
  • Retry policies: Per-step retry with configurable limits, intervals, and exit code filtering
  • Lifecycle hooks: onInit, onSuccess, onFailure, onAbort, onExit, onWait
  • Preconditions: Gate DAG or step execution on shell command results
  • High availability: Scheduler lock with stale detection for failover

Distributed Execution

The coordinator/worker architecture distributes DAG execution across multiple machines:

  • Coordinator: gRPC server that manages task distribution, worker registry, and health monitoring
  • Workers: Connect to the coordinator, pull tasks from the queue, execute DAGs locally, report results
  • Worker labels: Route DAGs to specific workers based on labels (e.g., gpu=true, region=us-east-1)
  • Health checks: HTTP health endpoints on coordinator and workers for load balancer integration
  • Queue system: File-based persistent queue with configurable concurrency limits
# Start coordinator
dagu coord

# Start workers (on separate machines)
DAGU_WORKER_LABELS=gpu=true,memory=64G dagu worker

See the distributed execution documentation for setup details.

CLI Reference

CommandDescription
dagu start <dag>Execute a DAG
dagu start-allStart HTTP server + scheduler
dagu serverStart HTTP server only
dagu schedulerStart scheduler only
dagu coordStart coordinator (distributed mode)
dagu workerStart worker (distributed mode)
dagu stop <dag>Stop a running DAG
dagu restart <dag>Restart a DAG
dagu retry <dag> <run-id>Retry a failed run
dagu dry <dag>Dry run β€” show what would execute
dagu status <dag>Show DAG run status
dagu history <dag>Show execution history
dagu validate <dag>Validate DAG YAML
dagu enqueue <dag>Add DAG to the execution queue
dagu dequeue <dag>Remove DAG from the queue
dagu cleanupClean up old run data
dagu migrateRun database migrations
dagu versionShow version

Environment Variables

Precedence: Command-line flags > Environment variables > Configuration file (~/.config/dagu/config.yaml)

Server

VariableDefaultDescription
DAGU_HOST127.0.0.1Bind address
DAGU_PORT8080HTTP port
DAGU_BASE_PATHβ€”Base path for reverse proxy
DAGU_HEADLESSfalseRun without web UI
DAGU_TZβ€”Timezone (e.g., Asia/Tokyo)
DAGU_LOG_FORMATtexttext or json
DAGU_CERT_FILEβ€”TLS certificate
DAGU_KEY_FILEβ€”TLS private key

Paths

VariableDefaultDescription
DAGU_HOMEβ€”Overrides all path defaults
DAGU_DAGS_DIR~/.config/dagu/dagsDAG definitions directory
DAGU_LOG_DIR~/.local/share/dagu/logsLog files
DAGU_DATA_DIR~/.local/share/dagu/dataApplication state

Authentication

VariableDefaultDescription
DAGU_AUTH_MODEbuiltinnone, basic, builtin, or OIDC
DAGU_AUTH_BASIC_USERNAMEβ€”Basic auth username
DAGU_AUTH_BASIC_PASSWORDβ€”Basic auth password
DAGU_AUTH_TOKEN_SECRET(auto)JWT signing secret
DAGU_AUTH_TOKEN_TTL24hJWT token lifetime

OIDC variables: DAGU_AUTH_OIDC_CLIENT_ID, DAGU_AUTH_OIDC_CLIENT_SECRET, DAGU_AUTH_OIDC_ISSUER, DAGU_AUTH_OIDC_SCOPES, DAGU_AUTH_OIDC_WHITELIST, DAGU_AUTH_OIDC_AUTO_SIGNUP, DAGU_AUTH_OIDC_DEFAULT_ROLE, DAGU_AUTH_OIDC_ALLOWED_DOMAINS.

Scheduler

VariableDefaultDescription
DAGU_SCHEDULER_PORT8090Health check port
DAGU_SCHEDULER_ZOMBIE_DETECTION_INTERVAL45sZombie run detection interval (0 to disable)
DAGU_SCHEDULER_LOCK_STALE_THRESHOLD30sHA lock stale threshold
DAGU_QUEUE_ENABLEDtrueEnable queue system

Coordinator / Worker

VariableDefaultDescription
DAGU_COORDINATOR_HOST127.0.0.1Coordinator bind address
DAGU_COORDINATOR_PORT50055Coordinator gRPC port
DAGU_COORDINATOR_HEALTH_PORT8091Coordinator health check port
DAGU_WORKER_IDβ€”Worker instance ID
DAGU_WORKER_MAX_ACTIVE_RUNS100Max concurrent runs per worker
DAGU_WORKER_HEALTH_PORT8092Worker health check port
DAGU_WORKER_LABELSβ€”Worker labels (key=value,key=value)

Peer TLS (gRPC)

VariableDefaultDescription
DAGU_PEER_CERT_FILEβ€”Peer TLS certificate
DAGU_PEER_KEY_FILEβ€”Peer TLS private key
DAGU_PEER_CLIENT_CA_FILEβ€”CA for client verification
DAGU_PEER_INSECUREtrueUse h2c instead of TLS

Git Sync

VariableDefaultDescription
DAGU_GITSYNC_ENABLEDfalseEnable Git sync
DAGU_GITSYNC_REPOSITORYβ€”Repository URL
DAGU_GITSYNC_BRANCHmainBranch to sync
DAGU_GITSYNC_AUTH_TYPEtokentoken or ssh
DAGU_GITSYNC_AUTOSYNC_ENABLEDfalseEnable periodic auto-pull
DAGU_GITSYNC_AUTOSYNC_INTERVAL300Sync interval in seconds

Full configuration reference: docs.dagu.sh/server-admin/reference

Documentation

Community

Development

Prerequisites: Go 1.26+, Node.js, pnpm

git clone https://github.com/dagucloud/dagu.git && cd dagu
make build    # Build frontend + Go binary
make test     # Run tests with race detection
make lint     # Run golangci-lint

See CONTRIBUTING.md for development workflow and code standards.

Acknowledgements

Premium Sponsors

@slashbinlabs

Supporters

@disizmj @Arvintian @yurivish @jayjoshi64 @alangrafu



Sponsor

Contributing

We welcome contributions of all kinds. See our Contribution Guide for details.

License

GNU GPLv3 - See LICENSE