{"id":48268180,"url":"https://github.com/dagucloud/dagu","last_synced_at":"2026-05-17T17:07:44.846Z","repository":{"id":37010139,"uuid":"484434975","full_name":"dagucloud/dagu","owner":"dagucloud","description":"A local-first workflow engine built the way it should be: declarative, file-based, self-contained, air-gapped ready. One binary that scales from laptop to distributed cluster. Persistent Workflow Operator handles creating and debugging workflows.","archived":false,"fork":false,"pushed_at":"2026-05-17T10:25:16.000Z","size":126925,"stargazers_count":3402,"open_issues_count":117,"forks_count":264,"subscribers_count":20,"default_branch":"main","last_synced_at":"2026-05-17T11:17:01.201Z","etag":null,"topics":["agentic-workflow","ai-agents","continuous-delivery","cron","dag","data-pipeline","devops","directed-acyclic-graph","durable-execution","durable-workflows","human-in-the-loop","job-scheduler","task-automation","task-scheduler","workflow-engine","workflow-management","workflow-orchestration","workflow-scheduler"],"latest_commit_sha":null,"homepage":"https://dagu.sh/oss","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dagucloud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["dagu-org"]}},"created_at":"2022-04-22T13:00:42.000Z","updated_at":"2026-05-16T22:05:04.000Z","dependencies_parsed_at":"2026-01-15T07:07:16.609Z","dependency_job_id":null,"html_url":"https://github.com/dagucloud/dagu","commit_stats":{"total_commits":1008,"total_committers":40,"mean_commits":25.2,"dds":0.09424603174603174,"last_synced_commit":"6d377ed7f2ea7b755df2455d5d6d6050e8813b56"},"previous_names":["yohamta/dagu","dagu-labs/dagu","yohamta/jobctl","hotaruswarm/dagu","dagu-dev/dagu","daguflow/dagu","dagu-org/dagu","dagu-go/dagu","dagucloud/dagu"],"tags_count":269,"template":false,"template_full_name":null,"purl":"pkg:github/dagucloud/dagu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagucloud%2Fdagu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagucloud%2Fdagu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagucloud%2Fdagu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagucloud%2Fdagu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dagucloud","download_url":"https://codeload.github.com/dagucloud/dagu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dagucloud%2Fdagu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33147340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T09:28:26.183Z","status":"ssl_error","status_checked_at":"2026-05-17T09:27:52.702Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-workflow","ai-agents","continuous-delivery","cron","dag","data-pipeline","devops","directed-acyclic-graph","durable-execution","durable-workflows","human-in-the-loop","job-scheduler","task-automation","task-scheduler","workflow-engine","workflow-management","workflow-orchestration","workflow-scheduler"],"created_at":"2026-04-04T22:00:29.165Z","updated_at":"2026-05-17T17:07:44.840Z","avatar_url":"https://github.com/dagucloud.png","language":"Go","funding_links":["https://github.com/sponsors/dagu-org","https://github.com/sponsors/dagucloud"],"categories":["Go","Workflow \u0026 Scheduling"],"sub_categories":["Workflow Frameworks"],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./assets/images/hero-logo.webp\" width=\"480\" alt=\"Dagu Logo\"\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://docs.dagu.sh/overview/changelog\"\u003e\u003cimg src=\"https://img.shields.io/github/release/dagucloud/dagu.svg?style=flat-square\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/dagucloud/dagu/actions/workflows/ci.yaml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/dagucloud/dagu/ci.yaml?style=flat-square\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://discord.gg/gpahPUjGRk\"\u003e\u003cimg src=\"https://img.shields.io/discord/1095289480774172772?style=flat-square\u0026logo=discord\" alt=\"Discord\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://bsky.app/profile/dagu-org.bsky.social\"\u003e\u003cimg src=\"https://img.shields.io/badge/Bluesky-0285FF?style=flat-square\u0026logo=bluesky\u0026logoColor=white\" alt=\"Bluesky\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\n  \u003cp\u003e\n    \u003ca href=\"https://docs.dagu.sh\"\u003eDocs\u003c/a\u003e |\n    \u003ca href=\"https://docs.dagu.sh/writing-workflows/examples\"\u003eExamples\u003c/a\u003e |\n    \u003ca href=\"./README_SCHEMA.md\"\u003eWorkflow Schema\u003c/a\u003e |\n    \u003ca href=\"https://discord.gg/gpahPUjGRk\"\u003eSupport \u0026 Community\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n## Local-first Control Plane for Existing Ops Automation and AI Agent Workflows\n\nDagu gives your automation a home. Run your existing scripts, containers, SQL jobs, and HTTP calls as visible, governed workflows with schedules, retries, logs, artifacts, human-in-the-loop, and observability without Airflow-level complexity.\n\nKeep your existing automation as shell scripts, Python scripts, containers, SSH commands, SQL jobs, HTTP calls, and AI harnesses. Define the workflow in plain YAML, run it with one binary, and get the operational layer that cron and ad hoc scripts are missing: dependencies, retries, queues, logs, artifacts, approvals, API/webhooks, optional distributed workers, and pinned external CLI tools for reproducible runs.\n\nDagu is local-first by default. API keys, private repositories, internal documents, customer data, Slack logs, and agent artifacts can stay inside your own machine or infrastructure instead of being handed to a cloud automation SaaS.\n\nFor a quick look at how workflows are defined, see the [examples](https://docs.dagu.sh/writing-workflows/examples). For a compact repository-level map of the YAML shape and current `run:`, `action:`, and `actions:` syntax, see the [Workflow Schema at a Glance](./README_SCHEMA.md).\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./assets/images/dagu-demo.gif\" width=\"720\" alt=\"Dagu demo showing the cockpit kanban view and YAML workflow editing\"\u003e\n\u003c/div\u003e\n\n| Run Details | Step Logs | Documents |\n|---|---|---|\n| ![Run details in dark mode](./assets/images/readme-run-details-dark.png) | ![Workflow logs in dark mode](./assets/images/readme-logs-dark.png) | ![Workflow documents in dark mode](./assets/images/readme-documents-dark.png) |\n\n**Try it live:** [Live Demo](https://dagu-demo-f5e33d0e.dagu.sh) (credentials: `demouser` / `demouser`)\n\n## Why Dagu?\n\n```sh\n  Traditional Orchestrator          Dagu\n  ┌────────────────────────┐        ┌──────────────────┐\n  │  Web Server            │        │                  │\n  │  Scheduler             │        │  dagu start-all  │\n  │  Worker(s)             │        │                  │\n  │  PostgreSQL            │        └──────────────────┘\n  │  Redis / RabbitMQ      │         Single binary.\n  │  Python Runtime        │         Self-hosted by default.\n  └────────────────────────┘         Adds scheduling, retries, and approvals around existing automation.\n    6+ services to manage\n```\n\nDagu was built for teams that need lightweight, self-hosted workflow orchestration without databases, brokers, or framework rewrites.\n\n## Performance\n\nDagu stores state in local files by default. How much it can run depends on the machine and the workload. CPU, disk speed, workflow duration, queue settings, and worker capacity all matter.\n\n- **Throughput:** On one machine, Dagu can run thousands of workflow runs per day when the hardware and workflow shape fit the workload.\n- **Load control:** Use [queues](https://docs.dagu.sh/server-admin/queues), concurrency limits, and optional [distributed workers](https://docs.dagu.sh/server-admin/distributed/) to decide how many runs execute at once and where they run.\n\n## Real-World Use Cases\n\nDagu is useful when teams need to consolidate scripts, cron jobs, server tasks, containers, data jobs, and approval-gated operational work into one visible, governed workflow system without rewriting the underlying automation.\n\n**Cron and legacy script management.** Run existing shell scripts, Python scripts, HTTP calls, and scheduled jobs without rewriting them. Dagu turns hidden cron jobs into visible workflows with dependencies, run status, logs, retries, approvals, and history.\n\n**ETL and data operations.** Run PostgreSQL, SQLite, or DuckDB queries, S3 transfers, `jq` transforms, validation steps, and reusable sub-workflows. Pin portable tools such as `jq` or `yq` in the DAG so workers do not depend on whatever version happens to be installed. Daily data workflows stay declarative, observable, and easy to retry when one step fails.\n\n**Media conversion.** Run `ffmpeg`, thumbnail extraction, audio normalization, image processing, and other compute-heavy jobs. Conversion work can run across distributed workers while status, history, logs, and artifacts stay in one persistence layer for monitoring, debugging, and retries.\n\n**Infrastructure and server automation.** Coordinate SSH backups, cleanup jobs, deploy scripts, patch windows, precondition checks, lifecycle hooks, and manual approvals. Remote operations get schedules, retries, notifications, and per-step logs without requiring operators to SSH into servers for every recovery.\n\n**GitHub-driven workflows.** Trigger Dagu runs from GitHub events, PR comments, releases, check reruns, `workflow_dispatch`, or `repository_dispatch` while the actual DAG executes on your own licensed Dagu server. This is useful for PR validation on private infrastructure, preview deployments, release workflows, and handing off long-running jobs from GitHub Actions to Dagu.\n\n**Container and Kubernetes workflows.** Compose workflows where each step can run a Docker image, Kubernetes Job, shell command, or validation step. Image-based tasks can be routed to the right workers without building a custom control plane around containers.\n\n**Customer support automation.** Run diagnostics, account repair jobs, data checks, and approval-gated support actions from a simple Web UI. Non-engineers can run reviewed workflows while engineers keep commands, logs, and results traceable.\n\n**IoT and edge workflows.** Run sensor polling, local cleanup, offline sync, health checks, and device maintenance jobs on small devices. The single binary and file-backed state work well on edge devices while still providing visibility through the Web UI.\n\n## Quick Start\n\n### Install\n\n**macOS/Linux:**\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.sh | bash\n```\n\n**Homebrew:**\n\n```sh\nbrew install dagu\n```\n\n**Windows (PowerShell):**\n\n```powershell\nirm https://raw.githubusercontent.com/dagucloud/dagu/main/scripts/installer.ps1 | iex\n```\n\n**Docker:**\n\n```sh\ndocker run --rm -v ~/.dagu:/var/lib/dagu -p 8080:8080 ghcr.io/dagucloud/dagu:latest dagu start-all\n```\n\n**Kubernetes (Helm):**\n\n```sh\nhelm repo add dagu https://dagucloud.github.io/dagu\nhelm repo update\nhelm install dagu dagu/dagu --set persistence.storageClass=\u003cyour-rwx-storage-class\u003e\n```\n\n\u003e Replace `\u003cyour-rwx-storage-class\u003e` with a StorageClass that supports `ReadWriteMany`. See [charts/dagu/README.md](./charts/dagu/README.md) for chart configuration.\n\nThe 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](https://docs.dagu.sh/getting-started/installation) for all options.\n\n### Create and run a workflow\n\nCreate a YAML file with your workflow definition. For example, create `review-readme.yaml` with the following content:\n\n```yaml\nworking_dir: ${DAG_RUN_ARTIFACTS_DIR}\n\nparams:\n  - name: REPO_URL\n    type: string\n    required: true\n\nartifacts:\n  enabled: true\n\nsteps:\n  - id: review_pr\n    action: agent.run\n    with:\n      task: |\n        Review the README.md file in ${REPO_URL}.\n        Return concise Markdown findings.\n      max_iterations: 10\n    stdout: ${DAG_RUN_ARTIFACTS_DIR}/review.md\n\n  - id: approval\n    action: noop\n    depends: [review_pr]\n    approval:\n      prompt: Review the review.md artifact. Approve to post an issue with the findings, or reject to skip.\n\n  - id: post_issue\n    run: gh issue create --title \"Review Findings\" --body-file \"${DAG_RUN_ARTIFACTS_DIR}/review.md\"\n    depends: [approval]\n```\n\nThis workflow uses the built-in [`agent.run` action](https://docs.dagu.sh/features/agent/step) and assumes a default model is configured in Agent Settings. It reviews a GitHub repository's README file, saves the agent's final output as an artifact, and then prompts for manual [approval](https://docs.dagu.sh/writing-workflows/yaml-specification#approval) before posting an issue with the findings. GitHub CLI (`gh`) is used in the final step to create the issue.\n\nRun the workflow with:\n\n```sh\ndagu start review-readme.yaml -- params REPO_URL=\u003cyour-repo-url\u003e\n```\n\n### Start the server\n\n```sh\ndagu start-all\n```\n\nVisit http://localhost:8080\n\n### Install the Dagu skill for AI coding tools\n\nInstall the Dagu authoring skill for Claude Code, Codex, Gemini CLI, and other AI coding tools:\n\n```sh\ngh skill install dagucloud/dagu dagu\n```\n\n## Deployment Models\n\nDagu can run on one machine, as a self-hosted production service, as a full managed Dagu Cloud server, or as a hybrid deployment with private workers inside your infrastructure.\n\nNeed the full breakdown, tradeoffs, and architecture notes? See the [Deployment Models guide](https://docs.dagu.sh/overview/deployment-models).\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\" align=\"center\" valign=\"top\"\u003e\n      \u003cstrong\u003eLocal Single-Server\u003c/strong\u003e\u003cbr\u003e\n      \u003cimg src=\"./assets/images/deployment-model-local.gif\" width=\"100%\" alt=\"Local single-server deployment model with one Dagu server handling scheduling and execution.\"\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\" align=\"center\" valign=\"top\"\u003e\n      \u003cstrong\u003eSelf-Hosted\u003c/strong\u003e\u003cbr\u003e\n      \u003cimg src=\"./assets/images/deployment-model-self-hosted.gif\" width=\"100%\" alt=\"Self-hosted deployment model with the Dagu server and workers running on your infrastructure.\"\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\" align=\"center\" valign=\"top\"\u003e\n      \u003cstrong\u003eDagu Cloud\u003c/strong\u003e\u003cbr\u003e\n      \u003cimg src=\"./assets/images/deployment-model-cloud.gif\" width=\"100%\" alt=\"Dagu Cloud deployment model with a managed Dagu server running in the cloud.\"\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\" align=\"center\" valign=\"top\"\u003e\n      \u003cstrong\u003eHybrid\u003c/strong\u003e\u003cbr\u003e\n      \u003cimg src=\"./assets/images/deployment-model-hybrid.gif\" width=\"100%\" alt=\"Hybrid deployment model with a managed Dagu Cloud server and private workers in your infrastructure.\"\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n| Model | Server | Execution | Best for |\n|------|--------|-----------|----------|\n| **Local single-server** | `dagu start-all` on one machine. | Same machine. | Development, small scheduled workloads, edge jobs, and simple internal automation. |\n| **Self-hosted** | Dagu server on your infrastructure. | Local execution or distributed workers on your infrastructure. | Teams that need ownership of networking, secrets, storage, runtime, and upgrade timing. |\n| **Dagu Cloud** | Full managed Dagu server in a dedicated, isolated gVisor instance on GKE. | Managed instance. | Teams that want Dagu operated for them without running the server themselves. |\n| **Hybrid** | Full managed Dagu Cloud server. | Private workers in your infrastructure over mTLS. | Docker steps, private networks, custom runtimes, secrets-heavy jobs, and data-local work. |\n\n### Licensing and Cloud\n\n- **Community self-host:** GPLv3. No license key required. You operate the server, storage, upgrades, networking, and workers. Start with the [installation guide](https://docs.dagu.sh/getting-started/installation/).\n- **Self-host license:** Adds SSO, RBAC, and audit logging to self-hosted Dagu. Licenses apply to Dagu servers, not workers, so execution can scale across your own infrastructure. See [self-host licensing](https://dagu.sh/pricing#self-host).\n- **Dagu Cloud managed instance:** Includes its own managed license. It can run workflows directly as a full Dagu server, and private workers can also run on your infrastructure using a worker mTLS bundle. See [Dagu Cloud](https://dagu.sh/cloud).\n\nManaged Dagu Cloud instances do not expose a Docker daemon or Docker socket. Workflows that need Docker step execution should use self-hosted Dagu or a private worker with Docker access.\n\n## Architecture\n\nDagu can run in three configurations:\n\n**Standalone:** A single `dagu start-all` process runs the HTTP server, scheduler, and executor. Suitable for single-machine deployments.\n\n**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.\n\n**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.\n\n```sh\nStandalone:\n\n  ┌─────────────────────────────────────────┐\n  │  dagu start-all                         │\n  │  ┌───────────┐ ┌───────────┐ ┌────────┐ │\n  │  │ HTTP / UI │ │ Scheduler │ │Executor│ │\n  │  └───────────┘ └───────────┘ └────────┘ │\n  │  File-based storage (logs, state, queue)│\n  └─────────────────────────────────────────┘\n\nDistributed:\n\n  ┌────────────┐                   ┌────────────┐\n  │ Scheduler  │                   │ HTTP / UI  │\n  │            │                   │            │\n  │ ┌────────┐ │                   └─────┬──────┘\n  │ │ Queue  │ │  Dispatch (gRPC)        │ Dispatch / GetWorkers\n  │ │(file)  │ │─────────┐               │ (gRPC)\n  │ └────────┘ │         │               │\n  └────────────┘         ▼               ▼\n                    ┌─────────────────────────┐\n                    │      Coordinator        │\n                    │  ┌───────────────────┐  │\n                    │  │ Dispatch Task     │  │\n                    │  │ Store (pending/   │  │\n                    │  │ claimed)          │  │\n                    │  └───────────────────┘  │\n                    └────────▲────────────────┘\n                             │\n                   Worker poll / task response\n                   Heartbeat / ReportStatus /\n                   StreamLogs (gRPC)\n                             │\n               ┌─────────────┴─────────────┐\n               │             │             │\n          ┌────┴───┐    ┌────┴───┐    ┌────┴───┐\n          │Worker 1│    │Worker 2│    │Worker N│ Sandbox execution of DAGs\n          │        │    │        │    │        │\n          └────────┘    └────────┘    └────────┘\n```\n\n## Embedded Go API (Experimental)\n\nGo applications can import Dagu and start DAG runs from the host process:\n\n```go\nimport \"github.com/dagucloud/dagu\"\n```\n\n```go\nengine, err := dagu.New(ctx, dagu.Options{\n\tHomeDir: \"/var/lib/myapp/dagu\",\n})\nif err != nil {\n\treturn err\n}\ndefer engine.Close(context.Background())\n\nrun, err := engine.RunYAML(ctx, []byte(`\nname: embedded\nparams:\n  - MESSAGE\nsteps:\n  - name: hello\n    run: echo \"${MESSAGE}\"\n`), dagu.WithParams(map[string]string{\n\t\"MESSAGE\": \"hello from the host app\",\n}))\nif err != nil {\n\treturn err\n}\n\nstatus, err := run.Wait(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(status.Status)\n```\n\nThe embedded API is experimental and may change before it is declared stable. It uses Dagu's YAML loader, built-in executors, and file-backed state. `RunFile` and `RunYAML` start runs asynchronously and return a run handle for `Wait`, `Status`, and `Stop`. Distributed embedded runs require an existing Dagu coordinator; embedded workers can be started with `NewWorker`.\n\nSee the [embedded API documentation](https://docs.dagu.sh/embedding/go-api) and [examples/embedded](./examples/embedded).\n\n## Workflow Examples\n\n### Parallel execution with dependencies\n\n```yaml\nsteps:\n  - id: extract\n    run: ./extract.sh\n  - id: transform_a\n    run: ./transform_a.sh\n    depends: [extract]\n  - id: transform_b\n    run: ./transform_b.sh\n    depends: [extract]\n  - id: load\n    run: ./load.sh\n    depends: [transform_a, transform_b]\n```\n\n```mermaid\n%%{init: {'theme': 'base', 'themeVariables': {'background': '#18181B', 'primaryTextColor': '#fff', 'lineColor': '#888'}}}%%\ngraph LR\n    A[extract] --\u003e B[transform_a]\n    A --\u003e C[transform_b]\n    B --\u003e D[load]\n    C --\u003e D\n    style A fill:#18181B,stroke:#22C55E,stroke-width:1.6px,color:#fff\n    style B fill:#18181B,stroke:#22C55E,stroke-width:1.6px,color:#fff\n    style C fill:#18181B,stroke:#22C55E,stroke-width:1.6px,color:#fff\n    style D fill:#18181B,stroke:#3B82F6,stroke-width:1.6px,color:#fff\n```\n\n### Sequential execution\n\n```yaml\nsteps:\n  - id: step_1\n    run: echo \"Step 1\"\n  - id: step_2\n    run: echo \"Step 2\"\n    depends: [step_1]\n```\n\n### Reproducible external tools\n\n```yaml\ntools:\n  - jqlang/jq@jq-1.7.1\n\nsteps:\n  - id: inspect\n    run: jq --version\n\n  - id: transform\n    run: jq '.items[] | .name' data.json\n    depends: [inspect]\n```\n\nDagu installs declared portable CLIs before the DAG run, exposes them on `PATH` for host command steps, and caches them on each worker. You do not need to install a separate tool manager; Dagu remains a single binary. See the [Tools documentation](https://docs.dagu.sh/writing-workflows/tools) for package syntax, immutable refs, distributed worker behavior, sub-DAG scoping, and current limitations.\n\n### Docker step\n\n```yaml\nsteps:\n  - name: build\n    container:\n      image: node:20-alpine\n    run: npm run build\n```\n\n### Kubernetes Pod execution\n\n```yaml\nsteps:\n  - name: batch-job\n    action: kubernetes.run\n    with:\n      namespace: production\n      image: my-registry/batch-processor:latest\n      resources:\n        requests:\n          cpu: \"2\"\n          memory: \"4Gi\"\n      command: ./process.sh\n```\n\n### SSH remote execution\n\n```yaml\nsteps:\n  - name: deploy\n    action: ssh.run\n    with:\n      host: prod-server.example.com\n      user: deploy\n      key: ~/.ssh/id_rsa\n      command: cd /var/www \u0026\u0026 git pull \u0026\u0026 systemctl restart app\n```\n\n### Sub-DAG composition\n\n```yaml\nsteps:\n  - name: extract\n    action: dag.run\n    with:\n      dag: etl/extract\n      params:\n        SOURCE: s3://bucket/data.csv\n  - name: transform\n    action: dag.run\n    with:\n      dag: etl/transform\n      params:\n        INPUT: ${extract.outputs.result}\n    depends: [extract]\n  - name: load\n    action: dag.run\n    with:\n      dag: etl/load\n      params:\n        DATA: ${transform.outputs.result}\n    depends: [transform]\n```\n\n### Retry and error handling\n\n```yaml\nsteps:\n  - name: flaky-api-call\n    run: curl -f https://api.example.com/data\n    retry_policy:\n      limit: 3\n      interval_sec: 10\n    continue_on:\n      failure: true\n```\n\n### Scheduling with overlap control and catch-up\n\n```yaml\nschedule:\n  - \"0 */6 * * *\"          # Every 6 hours\noverlap_policy: skip       # Skip if previous run is still active\ncatchup_window: \"5h\"       # Catch up missed runs when scheduler is down for up to 5 hours\n  \ntimeout_sec: 3600\nhandler_on:\n  failure:\n    run: notify-team.sh\n  exit:\n    run: cleanup.sh\n```\n\n### Built-in agent step with manual approval\n\n```yaml\nsteps:\n  - id: review\n    action: agent.run\n    with:\n      task: Review the README.md file and return concise Markdown findings.\n      max_iterations: 10\n    stdout: ${DAG_RUN_ARTIFACTS_DIR}/review.md\n\n  - id: approval\n    action: noop\n    depends: [review]\n    approval:\n      prompt: Review the review.md artifact. Approve to post an issue with the findings, or reject to skip.\n\n  - id: post_issue\n    run: gh issue create --title \"Review Findings\" --body-file \"${DAG_RUN_ARTIFACTS_DIR}/review.md\"\n    depends: [approval]\n```\n\nFor more examples, see the [Examples documentation](https://docs.dagu.sh/writing-workflows/examples).\n\n## Built-in and Custom Actions\n\nDagu includes built-in actions that run within the Dagu process (or worker). Local shell commands use `run`.\n\n| Field / Action | Purpose |\n|----------|---------|\n| [`run:` field](https://docs.dagu.sh/step-types/shell) | Local shell commands and scripts (bash, sh, PowerShell, custom shells) |\n| [`docker.run`](https://docs.dagu.sh/step-types/docker) | Run containers with registry auth, volume mounts, and resource limits |\n| [`kubernetes.run` / `k8s.run`](https://docs.dagu.sh/step-types/kubernetes) | Execute Kubernetes Jobs with namespace, image, and resource settings |\n| [`ssh.run`](https://docs.dagu.sh/step-types/ssh) | Remote command execution over SSH |\n| [`sftp.upload` / `sftp.download`](https://docs.dagu.sh/step-types/sftp) | File transfer over SFTP |\n| [`http.request`](https://docs.dagu.sh/step-types/http) | HTTP requests with headers, auth, and request bodies |\n| [`postgres.query`](https://docs.dagu.sh/step-types/sql/postgresql) / [`sqlite.query`](https://docs.dagu.sh/step-types/sql/sqlite) / `duckdb.query` | SQL queries, imports, and exports for PostgreSQL, SQLite, and DuckDB |\n| [`redis.\u003coperation\u003e`](https://docs.dagu.sh/step-types/redis) | Redis commands, pipelines, and Lua scripts |\n| [`s3.upload` / `s3.download` / `s3.list` / `s3.delete`](https://docs.dagu.sh/step-types/s3) | Upload, download, list, and delete S3 objects |\n| `file.stat` / `file.read` / `file.write` / `file.copy` / `file.move` / `file.delete` / `file.mkdir` / `file.list` | Local file operations without shell commands |\n| [`jq.filter`](https://docs.dagu.sh/step-types/jq) | JSON transformation using jq expressions |\n| [`archive.create` / `archive.extract` / `archive.list`](https://docs.dagu.sh/step-types/archive) | Create and extract zip/tar archives |\n| [`wait.duration` / `wait.until` / `wait.file` / `wait.http`](https://docs.dagu.sh/step-types/wait) | Wait for time, file state, or HTTP readiness |\n| [`mail.send`](https://docs.dagu.sh/step-types/mail) | Send email via SMTP |\n| [`template.render`](https://docs.dagu.sh/step-types/template) | Text generation with template rendering |\n| [`router.route`](https://docs.dagu.sh/step-types/router) | Conditional step routing based on values and patterns |\n| [`dag.run`](https://docs.dagu.sh/writing-workflows/control-flow) | Invoke another DAG as a sub-workflow with params and dependencies |\n| [`dag.enqueue`](https://docs.dagu.sh/writing-workflows/control-flow) | Queue another DAG asynchronously and continue after enqueue |\n| [`harness.run`](https://docs.dagu.sh/step-types/harness) | Run coding agent CLIs such as Claude Code, Codex, Copilot, OpenCode, and Pi |\n| [`agent.run`](https://docs.dagu.sh/features/agent/step) | Built-in agent action with tool use |\n\nYou can also define reusable actions with the top-level `actions` field. Custom actions expand to built-in actions during DAG load, so you can wrap a common shell, HTTP, SQL, or other pattern behind a typed interface with validated input.\n\n```yaml\nactions:\n  webhook.send:\n    input_schema:\n      type: object\n      additionalProperties: false\n      required: [url, text]\n      properties:\n        url:\n          type: string\n        text:\n          type: string\n    template:\n      action: http.request\n      with:\n        method: POST\n        url: {{ .input.url }}\n        headers:\n          Content-Type: application/json\n        body: |\n          {\"text\": {{ json .input.text }}}\n\nsteps:\n  - action: webhook.send\n    with:\n      url: https://hooks.example.com/ops\n      text: deploy complete\n```\n\nSee [Custom Actions](https://docs.dagu.sh/writing-workflows/custom-step-types) for the feature guide and [YAML Specification](https://docs.dagu.sh/writing-workflows/yaml-specification) for the exact `actions`, `action`, and `run` field behavior.\n\n## Security and Access Control\n\n### Authentication\n\nDagu supports three top-level authentication modes, configured via `DAGU_AUTH_MODE`:\n\n- **`none`** — No authentication\n- **`basic`** — HTTP Basic authentication\n- **`builtin`** — JWT-based authentication with user management, API keys, per-DAG webhook tokens, and optional OIDC/SSO integration\n\n### Role-Based Access Control\n\nWhen using `builtin` auth, five roles control access:\n\n| Role | Capabilities |\n|------|-------------|\n| `admin` | Full access including user management |\n| `manager` | Create, edit, delete, run, stop DAGs; view audit logs |\n| `developer` | Create, edit, delete, run, stop DAGs |\n| `operator` | Run and stop DAGs only (no editing) |\n| `viewer` | Read-only access |\n\nAPI keys can be created with independent role assignments. Audit logging tracks all actions.\n\n### TLS and Secrets\n\n- TLS for the HTTP server (`DAGU_CERT_FILE`, `DAGU_KEY_FILE`)\n- Mutual TLS for gRPC coordinator/worker communication (`DAGU_PEER_CERT_FILE`, `DAGU_PEER_KEY_FILE`, `DAGU_PEER_CLIENT_CA_FILE`)\n- Secret management with three providers: environment variables, files, and [HashiCorp Vault](https://www.vaultproject.io/)\n\n### Production Hardening\n\nFor self-hosted production deployments, treat network exposure and execution boundaries as the primary controls:\n\n- Prefer `auth.mode: builtin` for any shared or network-exposed instance. Use `basic` only for simple private setups, and avoid `none` outside isolated local development.\n- Keep `metrics: private` unless the metrics endpoint is reachable only on a trusted private network.\n- Bind Dagu to loopback or a private interface when possible. If you must use `0.0.0.0`, place it behind a trusted reverse proxy, TLS, and network-level access controls.\n- Leave `terminal.enabled: false` unless the instance is admin-only and tightly scoped.\n- In distributed deployments, set `peer.insecure=false` and configure peer TLS when coordinator and workers communicate across host or network boundaries.\n- Treat Docker socket mounts, root containers, and host-level executors as privileged access to the underlying machine.\n\nSee [Server Configuration](https://docs.dagu.sh/server-admin/server), [Docker deployment](https://docs.dagu.sh/server-admin/deployment/docker), and [Distributed execution](https://docs.dagu.sh/server-admin/distributed/) for the operator-focused guidance.\n\n## Observability\n\n### Prometheus Metrics\n\nDagu exposes Prometheus-compatible metrics:\n\n- `dagu_info` — Build information (version, Go version)\n- `dagu_uptime_seconds` — Server uptime\n- `dagu_dag_runs_total` — Total DAG runs by status\n- `dagu_dag_runs_total_by_dag` — Per-DAG run counts\n- `dagu_dag_run_duration_seconds` — Histogram of run durations\n- `dagu_dag_runs_currently_running` — Active DAG runs\n- `dagu_dag_runs_queued_total` — Queued runs\n- `dagu_workers_registered` — Registered distributed workers\n- `dagu_worker_info` — Worker heartbeat labels as key/value metadata\n- `dagu_worker_heartbeat_timestamp_seconds` — Last worker heartbeat timestamp\n- `dagu_worker_health_status` — Worker health by heartbeat freshness\n- `dagu_worker_pollers` — Worker poller capacity by state\n- `dagu_worker_running_tasks` — Running tasks per worker\n- `dagu_worker_oldest_running_task_age_seconds` — Age of the oldest running task per worker\n\n### Structured Logging\n\nJSON or text format logging (`DAGU_LOG_FORMAT`). Logs are stored per-run with separate stdout/stderr capture per step.\n\n### Notifications\n\n- Slack and Telegram bot integration for run monitoring and status updates\n- Email notifications on DAG success, failure, or wait status via SMTP\n- Per-DAG webhook endpoints with token authentication\n\n## Artifacts\n\n![Artifact browser in dark mode](./assets/images/readme-artifacts-dark.png)\n\nDagu runs can write arbitrary files into `DAG_RUN_ARTIFACTS_DIR`, and Dagu stores them per run as [Artifacts](https://docs.dagu.sh/writing-workflows/artifacts). In the [Web UI](https://docs.dagu.sh/overview/web-ui), operators can browse the file tree, preview Markdown, text, and image files inline, and download any artifact when they need the raw file.\n\nThis is useful for generated reports, screenshots, charts, exported JSON or CSV files, and other outputs that do not fit simple key/value [outputs](https://docs.dagu.sh/writing-workflows/outputs).\n\nSee the [Artifacts documentation](https://docs.dagu.sh/writing-workflows/artifacts) and the [Web UI guide](https://docs.dagu.sh/overview/web-ui) for the full artifact browser workflow and screenshots.\n\n## Scheduling and Reliability\n\n- **Cron scheduling** with timezone support and multiple schedule entries per DAG\n- **Overlap policies**: `skip` (default — skip if previous run is still active), `all` (queue all), `latest` (keep only the most recent)\n- **Catch-up scheduling**: Automatically runs missed intervals when the scheduler was down\n- **Zombie detection**: Identifies and handles stalled DAG runs (configurable interval, default 45s)\n- **Retry policies**: Per-step retry with configurable limits, intervals, and exit code filtering\n- **Lifecycle hooks**: `onInit`, `onSuccess`, `onFailure`, `onAbort`, `onExit`, `onWait`\n- **Preconditions**: Gate DAG or step execution on shell command results\n- **High availability**: Scheduler lock with stale detection for failover\n\n## Distributed Execution\n\nThe coordinator/worker architecture distributes DAG execution across multiple machines:\n\n- **Coordinator**: gRPC server that manages task distribution, worker registry, and health monitoring\n- **Workers**: Connect to the coordinator, pull tasks from the queue, execute DAGs locally, report results\n- **Worker labels**: Route DAGs to specific workers based on labels (e.g., `gpu=true`, `region=us-east-1`)\n- **Health checks**: HTTP health endpoints on coordinator and workers for load balancer integration\n- **Queue system**: File-based persistent queue with configurable concurrency limits\n\n```sh\n# Start coordinator\ndagu coordinator\n\n# Start workers (on separate machines)\nDAGU_WORKER_LABELS=gpu=true,memory=64G dagu worker\n```\n\nSee the [distributed execution documentation](https://docs.dagu.sh/server-admin/distributed/) for setup details.\n\n## CLI Reference\n\n| Command | Description |\n|---------|-------------|\n| `dagu start \u003cdag\u003e` | Execute a DAG |\n| `dagu start-all` | Start HTTP server + scheduler + coordinator |\n| `dagu server` | Start HTTP server only |\n| `dagu scheduler` | Start scheduler only |\n| `dagu coordinator` | Start coordinator (distributed mode) |\n| `dagu worker` | Start worker (distributed mode) |\n| `dagu stop \u003cdag\u003e` | Stop a running DAG |\n| `dagu restart \u003cdag\u003e` | Restart a DAG |\n| `dagu retry --run-id=\u003crun-id\u003e \u003cdag\u003e` | Retry a failed run |\n| `dagu dry \u003cdag\u003e` | Dry run — show what would execute |\n| `dagu status \u003cdag\u003e` | Show DAG run status |\n| `dagu history \u003cdag\u003e` | Show execution history |\n| `dagu validate \u003cdag\u003e` | Validate DAG YAML |\n| `dagu enqueue \u003cdag\u003e` | Add DAG to the execution queue |\n| `dagu dequeue \u003cqueue-name\u003e [--dag-run=\u003cdag\u003e:\u003crun-id\u003e]` | Remove a DAG-run from the queue |\n| `dagu cleanup \u003cdag\u003e` | Clean up old run data |\n| `dagu migrate history` | Migrate legacy run history |\n| `dagu version` | Show version |\n\n## Environment Variables\n\n**Precedence:** Command-line flags \u003e Environment variables \u003e Configuration file (`~/.config/dagu/config.yaml`)\n\n### Server\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_HOST` | `127.0.0.1` | Bind address |\n| `DAGU_PORT` | `8080` | HTTP port |\n| `DAGU_BASE_PATH` | — | Base path for reverse proxy |\n| `DAGU_HEADLESS` | `false` | Run without web UI |\n| `DAGU_TZ` | — | Timezone (e.g., `Asia/Tokyo`) |\n| `DAGU_LOG_FORMAT` | `text` | `text` or `json` |\n| `DAGU_CERT_FILE` | — | TLS certificate |\n| `DAGU_KEY_FILE` | — | TLS private key |\n\n### Paths\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_HOME` | — | Overrides all path defaults |\n| `DAGU_DAGS_DIR` | `~/.config/dagu/dags` | DAG definitions directory |\n| `DAGU_LOG_DIR` | `~/.local/share/dagu/logs` | Log files |\n| `DAGU_DATA_DIR` | `~/.local/share/dagu/data` | Application state |\n| `DAGU_TOOLS_DIR` | `{DAGU_DATA_DIR}/tools` | Managed DAG tool cache |\n\n### Authentication\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_AUTH_MODE` | `builtin` | `none`, `basic`, or `builtin` |\n| `DAGU_AUTH_BASIC_USERNAME` | — | Basic auth username |\n| `DAGU_AUTH_BASIC_PASSWORD` | — | Basic auth password |\n| `DAGU_AUTH_TOKEN_SECRET` | (auto) | JWT signing secret |\n| `DAGU_AUTH_TOKEN_TTL` | `24h` | JWT token lifetime |\n\nOIDC 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`.\n\n### Scheduler\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_SCHEDULER_PORT` | `8090` | Health check port |\n| `DAGU_SCHEDULER_ZOMBIE_DETECTION_INTERVAL` | `45s` | Zombie run detection interval (`0` to disable) |\n| `DAGU_SCHEDULER_LOCK_STALE_THRESHOLD` | `30s` | HA lock stale threshold |\n| `DAGU_QUEUE_ENABLED` | `true` | Enable queue system |\n\n### Coordinator / Worker\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_COORDINATOR_HOST` | `127.0.0.1` | Coordinator bind address |\n| `DAGU_COORDINATOR_PORT` | `50055` | Coordinator gRPC port |\n| `DAGU_COORDINATOR_HEALTH_PORT` | `8091` | Coordinator health check port |\n| `DAGU_WORKER_ID` | — | Worker instance ID |\n| `DAGU_WORKER_MAX_ACTIVE_RUNS` | `100` | Max concurrent runs per worker |\n| `DAGU_WORKER_HEALTH_PORT` | `8092` | Worker health check port |\n| `DAGU_WORKER_LABELS` | — | Worker labels (`key=value,key=value`) |\n\n### Peer TLS (gRPC)\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_PEER_CERT_FILE` | — | Peer TLS certificate |\n| `DAGU_PEER_KEY_FILE` | — | Peer TLS private key |\n| `DAGU_PEER_CLIENT_CA_FILE` | — | CA for client verification |\n| `DAGU_PEER_INSECURE` | `true` | Use h2c instead of TLS |\n\n### Git Sync\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `DAGU_GITSYNC_ENABLED` | `false` | Enable Git sync |\n| `DAGU_GITSYNC_REPOSITORY` | — | Repository URL |\n| `DAGU_GITSYNC_BRANCH` | `main` | Branch to sync |\n| `DAGU_GITSYNC_AUTH_TYPE` | `token` | `token` or `ssh` |\n| `DAGU_GITSYNC_AUTOSYNC_ENABLED` | `false` | Enable periodic auto-pull |\n| `DAGU_GITSYNC_AUTOSYNC_INTERVAL` | `300` | Sync interval in seconds |\n\nFull configuration reference: [docs.dagu.sh/server-admin/reference](https://docs.dagu.sh/server-admin/reference)\n\n## Documentation\n\n- [Getting Started](https://docs.dagu.sh/getting-started/installation) — Installation and first workflow\n- [Writing Workflows](https://docs.dagu.sh/writing-workflows/examples) — YAML syntax, scheduling, execution control\n- [Workflow Schema at a Glance](./README_SCHEMA.md) — Repository-level overview of the current YAML schema\n- [Tools](https://docs.dagu.sh/writing-workflows/tools) — Pin external CLI packages in DAGs for reproducible host command steps\n- [Actions](https://docs.dagu.sh/step-types/shell) — [Shell](https://docs.dagu.sh/step-types/shell), [Docker](https://docs.dagu.sh/step-types/docker), [Kubernetes](https://docs.dagu.sh/step-types/kubernetes), [HTTP](https://docs.dagu.sh/step-types/http), [SQL](https://docs.dagu.sh/step-types/sql/), [Harness](https://docs.dagu.sh/step-types/harness), [Agent Step](https://docs.dagu.sh/features/agent/step), and [Custom Actions](https://docs.dagu.sh/writing-workflows/custom-step-types)\n- [Distributed Execution](https://docs.dagu.sh/server-admin/distributed/) — Coordinator/worker setup\n- [Authentication](https://docs.dagu.sh/server-admin/authentication/) — RBAC, OIDC, API keys\n- [Git Sync](https://docs.dagu.sh/server-admin/git-sync) — Version-controlled DAG definitions\n- [GitHub Integration](https://docs.dagu.sh/github-integration/) — Trigger Dagu runs from GitHub events, PR comments, releases, checks, and dispatches\n- [AI Agent](https://docs.dagu.sh/features/agent/) — AI-assisted workflow authoring\n- [Changelog](https://docs.dagu.sh/overview/changelog)\n\n## Community\n\n- [Discord](https://discord.gg/gpahPUjGRk) — Questions and discussion\n- [GitHub Issues](https://github.com/dagucloud/dagu/issues) — Bug reports and feature requests\n- [Bluesky](https://bsky.app/profile/dagu-org.bsky.social)\n\n## Development\n\n**Prerequisites:** [Go 1.26+](https://go.dev/doc/install), [Node.js](https://nodejs.org/en/download/), [pnpm](https://pnpm.io/installation)\n\n```sh\ngit clone https://github.com/dagucloud/dagu.git \u0026\u0026 cd dagu\nmake build    # Build frontend + Go binary\nmake test     # Run tests with race detection\nmake lint     # Run golangci-lint\n```\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for development workflow and code standards.\n\n## Acknowledgements\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch3\u003ePremium Sponsors\u003c/h3\u003e\n  \u003ca href=\"https://github.com/slashbinlabs\"\u003e\n    \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2Fslashbinlabs.png\u0026w=150\u0026h=150\u0026fit=cover\u0026mask=circle\" width=\"100\" height=\"100\" alt=\"@slashbinlabs\"\u003e\n  \u003c/a\u003e\n\n  \u003ch3\u003eSupporters\u003c/h3\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/gyger\"\u003e\n      \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2Fgyger.png\u0026w=128\u0026h=128\u0026fit=cover\u0026mask=circle\" width=\"50\" alt=\"@gyger\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/disizmj\"\u003e\n      \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2Fdisizmj.png\u0026w=128\u0026h=128\u0026fit=cover\u0026mask=circle\" width=\"50\" alt=\"@disizmj\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Arvintian\"\u003e\n      \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2FArvintian.png\u0026w=128\u0026h=128\u0026fit=cover\u0026mask=circle\" width=\"50\" alt=\"@Arvintian\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/yurivish\"\u003e\n      \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2Fyurivish.png\u0026w=128\u0026h=128\u0026fit=cover\u0026mask=circle\" width=\"50\" alt=\"@yurivish\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/jayjoshi64\"\u003e\n      \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2Fjayjoshi64.png\u0026w=128\u0026h=128\u0026fit=cover\u0026mask=circle\" width=\"50\" alt=\"@jayjoshi64\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/alangrafu\"\u003e\n      \u003cimg src=\"https://wsrv.nl/?url=https%3A%2F%2Fgithub.com%2Falangrafu.png\u0026w=128\u0026h=128\u0026fit=cover\u0026mask=circle\" width=\"50\" alt=\"@alangrafu\"\u003e\n    \u003c/a\u003e\n  \u003c/p\u003e\n\n  \u003cbr/\u003e\u003cbr/\u003e\n\n  \u003ca href=\"https://github.com/sponsors/dagucloud\"\u003e\n    \u003cimg src=\"https://img.shields.io/static/v1?label=Sponsor\u0026message=%E2%9D%A4\u0026logo=GitHub\u0026color=%23fe8e86\" width=\"150\" alt=\"Sponsor\"\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n## Contributing\n\nWe welcome contributions of all kinds. See our [Contribution Guide](./CONTRIBUTING.md) for details.\n\n\u003ca href=\"https://github.com/dagucloud/dagu/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=dagucloud/dagu\" /\u003e\n\u003c/a\u003e\n\n## License\n\nGNU GPLv3 - See [LICENSE](./LICENSE). See [LICENSING.md](./LICENSING.md) for embedded API and commercial embedding notes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdagucloud%2Fdagu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdagucloud%2Fdagu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdagucloud%2Fdagu/lists"}