Skip to content

Writing Workflows

A Dagu workflow is a YAML file with a steps list. Start with a command you already run, then add dependencies and operational behavior only when the workflow needs them.

Start with one command

Save this as hello.yaml:

yaml
steps:
  - run: echo "Hello from Dagu"

Run it:

bash
dagu start hello.yaml

That is a complete workflow. A name, schedule, queue, parameter block, and runner configuration are not required.

An id is optional for an isolated step. Add one when another step needs to depend on it or reference its output:

yaml
steps:
  - id: hello
    run: echo "Hello from Dagu"

  - run: echo "Finished"
    depends: hello

Add dependencies to build a DAG

Each step's depends field lists the steps that must succeed first. Dagu starts every step whose dependencies are ready.

yaml
steps:
  - id: fetch
    run: ./fetch.sh

  - id: clean
    run: ./clean.sh
    depends: fetch

  - id: analyze
    run: ./analyze.sh
    depends: fetch

  - id: report
    run: ./report.sh
    depends: [clean, analyze]

The run proceeds in three stages:

  1. fetch runs first.
  2. clean and analyze become ready together, so they run in parallel.
  3. report waits for both branches.

There is no separate parallel-execution configuration. Parallelism follows directly from the graph.

Validate, preview, and inspect runs

Use the CLI while developing a workflow:

bash
dagu validate pipeline.yaml  # Check the YAML
dagu dry pipeline.yaml       # Show the execution plan
dagu start pipeline.yaml     # Run it now
dagu history pipeline        # List recent runs

Start the server to inspect the same workflows in the Web UI:

bash
dagu start-all --dags .

Open http://localhost:8080 to see the graph, live step status, logs, run history, and controls for starting, stopping, and retrying runs.

Add operational behavior when needed

Top-level fields configure the workflow as a whole. Fields inside a step configure that command.

Schedule it and retry failures

yaml
schedule: "0 2 * * *"

steps:
  - run: ./nightly-sync.sh
    retry_policy:
      limit: 3
      interval_sec: 30

The scheduler starts this workflow every day at 02:00. A failed command is retried up to three times with 30 seconds between attempts. See Scheduling and Durable Execution.

Accept parameters

yaml
params:
  - ENVIRONMENT: staging

steps:
  - run: ./deploy.sh "${params.ENVIRONMENT}"

Override the value when starting the workflow:

bash
dagu start deploy.yaml -- ENVIRONMENT=production

Parameters can also be typed and validated before a run starts. See Parameters.

Run the workflow in a shared container

yaml
container:
  image: python:3.13

steps:
  - run: python report.py

All steps share one workflow container and its filesystem. See Container.

Use built-in actions

run executes a command through a shell. For operations with structured inputs, set action and pass its configuration under with. Actions use the same dependencies, retries, conditions, status tracking, and logs as command steps.

Run one step in Docker

Use docker.run when a step needs its own container:

yaml
steps:
  - id: container_job
    action: docker.run
    with:
      image: alpine:3
      auto_remove: true
      command: echo "Hello from Docker"

The container is separate from containers used by other steps. See Docker.

Run a command over SSH

yaml
steps:
  - id: check_server
    action: ssh.run
    with:
      user: deploy
      host: app.example.com
      command: uptime

Dagu captures the remote command's status, stdout, and stderr as a normal step result. See SSH.

Route to selected steps

router.route provides switch-style branching. Target steps implicitly depend on the router; steps in unselected routes are skipped.

yaml
type: graph

params:
  - TARGET: staging

steps:
  - id: choose_target
    action: router.route
    with:
      value: ${params.TARGET}
      routes:
        staging: [deploy_staging]
        production: [deploy_production]

  - id: deploy_staging
    run: ./deploy.sh staging

  - id: deploy_production
    run: ./deploy.sh production

Exact values and re: regular-expression patterns can each select one or more target steps. See Router.

Run a coding agent

harness.run launches an external coding-agent CLI as a workflow step:

yaml
steps:
  - id: review
    action: harness.run
    with:
      provider: codex
      prompt: Review the current branch and report correctness risks

The provider CLI must be installed and authenticated on the worker, or supplied through a containerized harness. See Harness and Sandboxed Execution.

Wait for a person

yaml
steps:
  - id: confirm
    action: human.task
    with:
      prompt: Deploy to production?

  - id: deploy
    run: ./deploy.sh
    depends: confirm

The run enters Waiting at confirm and releases its worker slot. Complete the task from the Web UI, REST API, or CLI to resume the same run. See Human Tasks.

Other built-in actions cover HTTP requests, SQL, Kubernetes jobs, S3, Git, files, archives, templates, and persistent state.

Find the next topic

When you want to…Read
Learn step fields, scripts, dependencies, and defaultsWorkflow Basics
Pass parameters, outputs, and files between stepsData & Variables
Add conditions, loops, parallel iteration, or sub-DAGsControl Flow
Configure retries, timeouts, handlers, and failure behaviorDurable Execution and Error Handling
Run HTTP, SQL, SSH, Docker, Kubernetes, or other actionsBuilt-in Actions
Start from copyable workflowsExamples
Look up every supported fieldYAML Specification

Dagu is open source under the GNU General Public License v3.0.