Dagu 2.21.0 配置参数详解
逐字段实测 Dagu 2.21.0 三层配置:DAG YAML(steps 依赖、retry_policy 真实重试、env/params、output 传递、handler_on 失败钩子、schedule、SMTP 邮件)、base.yaml 全局默认值、dagu.env 服务端变量。附生产配置模板、YAML 语法报错实测与 FAQ。
Dagu 2.21.0 配置参数详解
目标:逐字段讲透 Dagu 2.21.0 的三层配置——工作流定义 YAML(DAG 文件)、全局继承配置(base.yaml)、服务端环境变量(dagu.env),所有字段含义以官方 base.yaml 内置注释与实测行为为准,每个字段配实测回显。全文命令与回显均在 Ubuntu 22.04 + Dagu 2.21.0 环境逐条实测通过(含重试、失败钩子、邮件通知、调度识别等完整闭环)。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)。
- Dagu 版本:2.21.0(
dagu version实测回显2.21.0),systemd 服务托管(dagu.service)。 - 数据目录:
DAGU_HOME=/var/lib/dagu(dags/ 工作流、logs/ 日志、data/ 状态)。 - 服务端配置:
/etc/dagu/dagu.env(DAGU_HOST=0.0.0.0、DAGU_PORT=8114,安装默认端口 8080,本机 8080 已占用故改 8114)。 - 全局配置:
/var/lib/dagu/base.yaml(首次启动自动生成,含全量字段注释,是官方参数文档的可执行形态)。 - 辅助实测组件:本地 SMTP 调试服务器(127.0.0.1:1025,捕获通知邮件)、本地 HTTP 接收器(127.0.0.1:1026,捕获 Webhook)。
- CLI 约定:本文所有 CLI 命令均在
export DAGU_HOME=/var/lib/dagu下执行,保证与服务端操作同一套工作流目录。
二、前置条件
- 已按《Ubuntu 22.04 安装 Dagu 2.21.0 指南》完成安装,
systemctl is-active dagu为active。 - 确认配置三层各自的生效优先级(官方 base.yaml 头部注释原文):
Precedence: global base -> workspace base -> DAG,即全局 base.yaml → 工作区 base.yaml → DAG 文件自身,下层覆盖上层同名键;DAG 的env:是追加而非替换全局 env。
三、参数查看与修改方式
三套配置各有查看入口,先建立全局认识再逐字段深入。
3.1 DAG 文件(一层一工作流)
位置 $DAGU_HOME/dags/*.yaml,一个文件一个工作流。列出已加载的工作流:
dagu ls
实测回显:
NAME
c1-fail-demo
c1-retry-demo
c1-schedule-demo
d2-check-demo
d2-webhook-demo
example-01-basic-sequential
example-02-parallel-execution
example-03-scheduling
example-04-nested-workflows
example-05-template-and-file
example-06-retry-on-failure
修改后无需重启服务:调度器监听文件变化,实测日志 msg="DAG added/updated" name=c1-retry-demo.yaml,保存即生效。
3.2 schema 子命令(内置字段文档)
Dagu 内置 schema 文档查询,不用翻网页:
dagu schema --help
实测回显(节选):
Display schema documentation for DAG or config
Usage:
dagu schema [dag|config] [flags]
3.3 服务端环境变量(dagu.env)
systemd 单元通过 EnvironmentFile=/etc/dagu/dagu.env 注入,改后需 systemctl restart dagu。查看当前值:
cat /etc/dagu/dagu.env
实测回显:
DAGU_HOME=/var/lib/dagu
DAGU_HOST=0.0.0.0
DAGU_PORT=8114
3.4 修改方式小结
| 层 | 文件 | 生效方式 |
|---|---|---|
| DAG 工作流 | $DAGU_HOME/dags/*.yaml | 保存即生效(文件监听) |
| 全局继承 | $DAGU_HOME/base.yaml | 保存即生效(官方注释:Changes to global or workspace defaults are reloaded automatically) |
| 服务端 | /etc/dagu/dagu.env | systemctl restart dagu |
四、配置体系总览
先看一张「哪个诉求改哪层」的路标表,再进入字段详解:
| 诉求 | 配置位置 | 关键字段 |
|---|---|---|
| 某工作流的定时/步骤/重试/通知 | DAG 文件 | schedule、steps、retry_policy、handler_on |
| 所有工作流共享的默认值 | base.yaml | type、overlap_policy、hist_retention_days、smtp、mail_on |
| 监听地址/端口/数据目录 | dagu.env | DAGU_HOST、DAGU_PORT、DAGU_HOME |
💡 技术拓展:定时调度里的 cron 表达式存在两派写法——标准 5 段(分 时 日 月 周,本文所用)与扩展 6/7 段(Quartz 系,含秒与年份)。Dagu 采用标准 5 段并支持
CRON_TZ=时区前缀声明时区; Quartz 系(如某些 Java 调度器)字段更多但迁移时要删秒位。本文因与 crontab 迁移场景对齐,采用标准 5 段。
五、DAG YAML 核心字段详解
以下每个字段均来自实测 DAG 文件,YAML 直接决定执行行为。
5.1 steps 与 depends:步骤与依赖编排
steps 是 DAG 的主体,每个步骤用 id 标识、run 给 shell 命令、depends 声明依赖(单值或数组)。实测 DAG(保存为 $DAGU_HOME/dags/c1-retry-demo.yaml):
description: "C1 field test - deps retry env output"
type: graph
env:
- APP_ENV: production
- REPORT_DIR: /var/lib/dagu/reports
steps:
- id: prepare
run: echo "prepare env=$APP_ENV dir=$REPORT_DIR"
output: PREP_MSG
- id: flaky
working_dir: ${context.paths.artifacts_dir}
run: |
if [ -f marker ]; then
echo "flaky recovered, got: ${PREP_MSG}"
else
touch marker
echo "simulated transient failure"
exit 1
fi
depends: [prepare]
retry_policy:
limit: 3
interval_sec: 2
- id: finish
run: echo "workflow done"
depends: [flaky]
逐项说明:type: graph 按依赖图调度(无依赖步骤并行),type: chain 则严格按定义顺序串行;run 支持多行块标量(整段脚本);output: PREP_MSG 把步骤 stdout 捕获进变量,后续步骤用 ${PREP_MSG} 引用;working_dir 指定步骤工作目录,${context.paths.artifacts_dir} 是本次运行的产物目录(每次运行独立,天然隔离临时文件);depends: [prepare] 写成 depends: prepare 等价。
执行前先静态校验与干跑:
dagu validate /var/lib/dagu/dags/c1-retry-demo.yaml
dagu dry /var/lib/dagu/dags/c1-retry-demo.yaml
实测回显(dry):
time=2026-10-19T05:06:47.397Z level=INFO msg="Step started" dag=c1-retry-demo run-id=034iRmy23vJKhb3wcB6jcK step=prepare
time=2026-10-19T05:06:47.402Z level=INFO msg="Step started" dag=c1-retry-demo run-id=034iRmy23vJKhb3wcB6jcK step=flaky
time=2026-10-19T05:06:47.402Z level=INFO msg="Step started" dag=c1-retry-demo run-id=034iRmy23vJKhb3wcB6jcK step=finish
time=2026-10-19T05:06:47.403Z level=INFO msg="Dry-run completed" dag=c1-retry-demo run-id=034iRmy23vJKhb3wcB6jcK params=[]
Succeeded - 2026-10-19T05:06:47Z
dag: c1-retry-demo (0s)
├─log: /var/lib/dagu/logs/c1-retry-demo/dag-run_20261019_050647Z_034iRmy23vJKhb3wcB6jcK/dag-run_20261019.050647.396.034iRmy2.log
│
├─prepare [succeeded]
│ └─echo "prepare env=$APP_ENV dir=$REPORT_DIR"
│
├─flaky [succeeded]
│
└─finish [succeeded]
└─echo "workflow done"
Result: Succeeded
真实执行:
dagu start /var/lib/dagu/dags/c1-retry-demo.yaml
实测回显:
Succeeded - 2026-10-19T05:06:53Z
dag: c1-retry-demo (2.0s)
├─log: /var/lib/dagu/logs/c1-retry-demo/dag-run_20261019_050653Z_034iRn7eRdvuJNPbziddBy/dag-run_20261019.050653.517.034iRn7e.log
│
├─prepare (0s) [succeeded]
│ ├─echo "prepare env=$APP_ENV dir=$REPORT_DIR"
│ │
│ └─stdout: /var/lib/dagu/logs/c1-retry-demo/dag-run_20261019_050653Z_034iRn7eRdvuJNPbziddBy/run_20261019_050653Z_22fd17/prepare.20261019.050653.527.034iRn7e.out
│ prepare env=production dir=/var/lib/dagu/reports
│
├─flaky (2.0s) [succeeded]
│ └─stdout: /var/lib/dagu/logs/c1-retry-demo/dag-run_20261019_050653Z_034iRn7eRdvuJNPbziddBy/run_20261019_050653Z_22fd17/flaky.20261019.050653.533.034iRn7e.out
│ simulated transient failure
│ flaky recovered, got: prepare env=production dir=/var/lib/dagu/reports
│
└─finish (0s) [succeeded]
├─echo "workflow done"
│
└─stdout: /var/lib/dagu/logs/c1-retry-demo/dag-run_20261019_050653Z_034iRn7eRdvuJNPbziddBy/run_20261019_050653Z_22fd17/finish.20261019.050655.541.034iRn7e.out
workflow done
Result: Succeeded
三个关键行为全部验证:env 变量在步骤中展开(env=production dir=/var/lib/dagu/reports);flaky 首次失败后自动重试成功(总耗时 2.0s = interval_sec 的重试间隔);output 变量 PREP_MSG 跨步骤传递(重试输出里带出了 prepare 的完整回显)。
5.2 retry_policy:重试策略
步骤级字段,继承自全局 defaults.retry_policy(见第六章)。已实测字段:
| 字段 | 实测值 | 含义 |
|---|---|---|
| limit | 3 | 最大重试次数 |
| interval_sec | 2 | 重试间隔秒数;backoff: true 时按指数倍增(next = interval × backoff^attempt),max_interval_sec 封顶 |
| exit_code | 未测(默认全部失败码重试) | 仅对指定退出码重试,如 [1, 2] |
失败与重试在日志里的原始记录($DAGU_HOME/logs/c1-retry-demo/dag-run_*/dag-run_*.log):
time=2026-10-19T05:06:53.537Z level=INFO msg="Step execution failed; retrying" step=flaky err="exit status 1" retry=0 exit-code=1
日志目录布局(stdout 与 stderr 分离,默认 log_output: separate):
dag-run_20261019_050653Z_034iRn7eRdvuJNPbziddBy/
├── dag-run_20261019.050653.517.034iRn7e.log # DAG 级执行日志(调度/重试记录)
└── run_20261019_050653Z_22fd17/
├── prepare.20261019.050653.527.034iRn7e.out
├── prepare.20261019.050653.527.034iRn7e.err
├── flaky.20261019.050653.533.034iRn7e.out
└── finish.20261019.050655.541.034iRn7e.out
💡 技术拓展:失败重试有两种粒度——步骤级(本文所用 retry_policy,只重跑失败步骤)与 DAG 级(base.yaml 注释中的
retry_policy: {limit, interval_sec},失败后整个 DAG 换新 run-ID 重跑,官方注释明确默认关闭因为工作流可能有非幂等副作用)。另有运行后手动重试:UI 的 retry 按钮与dagu retry子命令(同 run-ID 重放)。本文步骤用幂等的 marker 文件演示,实际采用步骤级重试,粒度细、影响面小。
5.3 schedule:定时调度
description: "C1 schedule test - daily 03:00"
schedule: "0 3 * * *"
steps:
- id: job
run: echo "daily job running"
实测回显(保存后 API 视角的调度识别,UI 列表页同源数据):
{"dag":{"name":"c1-schedule-demo","schedule":[{"expression":"0 3 * * *","kind":"cron"}],...},"latestDAGRun":{"status":"not_started"}}
写法要点:多时段用数组 schedule: ["0 2 * * *", "0 12 * * *"];带时区写 schedule: "CRON_TZ=Asia/Shanghai 0 3 * * *";配合 base.yaml 的 catchup_window: "6h",调度器重启后 6 小时内错过的 cron 间隔会自动补跑(官方注释:max 1000)。overlap_policy: skip(默认)表示上一轮未结束时新触发放弃;all 排队、latest 只保留最新。
5.4 env 与 params:环境变量与运行参数
env 是静态环境变量(实测见 5.1);params 是可运行时覆盖的参数,支持 JSON Schema 校验(官方示例 example-03 原文):
params:
- name: environment
type: string
enum: [dev, staging, prod]
default: staging
description: Target environment for this run
- name: batch_size
type: integer
minimum: 1
maximum: 1000
default: 100
description: Number of records to process
env:
- LOG_LEVEL: info
steps:
- id: plan
run: echo "Planning ${params.batch_size} records for ${params.environment}"
引用语法区分两族:参数 ${params.name}、环境变量 ${env.NAME}、上下文 ${context.paths.artifacts_dir}(均带命名空间);而 env: 里定义的变量在 shell 中可直接 $APP_ENV 展开(实测 5.1 输出)。UI 触发时可编辑参数(run_config.disable_param_edit: false 控制)。
5.5 handler_on:生命周期钩子
DAG 级钩子,事件含 init/success/failure/abort/exit/wait。实测失败钩子($DAGU_HOME/dags/c1-fail-demo.yaml):
description: "C1 failure handler test"
handler_on:
failure:
run: 'echo "ALERT: c1-fail-demo failed"'
env:
- ALERT_LEVEL: critical
steps:
- id: boom
run: sh -c "echo boom-to-stderr >&2; exit 3"
执行实测:
dagu start /var/lib/dagu/dags/c1-fail-demo.yaml
实测回显:
Failed - 2026-10-19T05:07:46Z
dag: c1-fail-demo (0s)
├─log: /var/lib/dagu/logs/c1-fail-demo/dag-run_20261019_050746Z_034iRoTL75JMlepuMroaYa/dag-run_20261019.050746.744.034iRoTL.log
│
├─boom (0s) [failed]
│ ├─sh -c "echo boom-to-stderr >&2; exit 3"
│ │
│ ├─stderr: /var/lib/dagu/logs/c1-fail-demo/dag-run_20261019_050746Z_034iRoTL75JMlepuMroaYa/run_20261019_050746Z_abd7b1/boom.20261019.050746.752.034iRoTL.err
│ │ boom-to-stderr
│ │
│ └─error: exit status 3
│
└─onFailure (0s) [succeeded]
├─echo "ALERT: c1-fail-demo failed"
│
└─stdout: /var/lib/dagu/logs/c1-fail-demo/dag-run_20261019_050746Z_034iRoTL75JMlepuMroaYa/run_20261019_050746Z_abd7b1/onFailure.20261019.050746.756.034iRoTL.out
ALERT: c1-fail-demo failed
Result: Failed
行为解读:boom 以 exit 3 失败后,onFailure 钩子作为独立步骤执行并成功;钩子是完整 step 定义,可带 env、timeout 等。钩子执行顺序固定为「失败步骤 → onFailure」,退出码反映主流程失败。注意 run 值里含冒号/引号时整个值加引号,否则 YAML 解析报错(实测报错见第八章 Q1)。
5.6 smtp / error_mail / mail_on:邮件通知
邮件三件套建议配在 base.yaml(全局生效,所有 DAG 继承),实测追加到 /var/lib/dagu/base.yaml 尾部:
smtp:
host: 127.0.0.1
port: "1025"
error_mail:
from: dagu@example.com
to: ops@example.com
prefix: "[DAGU]"
attach_logs: false
mail_on:
failure: true
逐项说明:smtp.host/port 服务器与端口(生产用 587 STARTTLS 或 465,另支持 oauth 段接 Microsoft 365/Google);error_mail 失败邮件的发件人/收件人/主题前缀/是否附日志(to 也可为数组多收件人);mail_on 开关三类事件邮件(failure/success/wait)。配套还有 info_mail(成功通知)、wait_mail(等待人工审批通知)。
执行失败的 DAG 后,本地 SMTP 服务器实测收到邮件(回显摘自 SMTP 调试日志):
---------- MESSAGE FOLLOWS ----------
mail options: ['BODY=8BITMIME']
b'To: ops@example.com'
b'From: dagu@example.com'
b'Subject: [DAGU] c1-fail-demo (failed)'
b'Date: Mon, 19 Oct 2026 05:09:15 +0000'
b'MIME-Version: 1.0'
b'Content-Type: text/html; charset=UTF-8'
b'Content-Transfer-Encoding: base64'
主题规则为 {prefix} {DAG名} ({状态}),正文为 HTML 模板(base64 编码传输)。
5.7 log_dir 与日志目录
DAG 级 log_dir 可把某工作流日志指到自定义路径;不设时默认 $DAGU_HOME/logs/<DAG名>/。实测目录结构见 5.2。日志保留由 base.yaml 全局控制:hist_retention_days: 30(按天)或 hist_retention_runs: 100(按条数,二选一),过期历史自动清理(也可手动 dagu rm --history)。
六、全局配置(base.yaml 与 dagu.env)
6.1 base.yaml 已启用的默认值(实测文件摘录)
首次启动生成的 base.yaml 即官方推荐起点,已启用项与默认值:
| 字段 | 默认值 | 含义 |
|---|---|---|
| type | graph | 依赖图调度(chain 为顺序链) |
| overlap_policy | skip | 运行中再触发则丢弃(all 排队 / latest 留最新) |
| log_output | separate | stdout/stderr 分离为 .out/.err(merged 合并单文件) |
| hist_retention_days | 30 | 执行历史保留天数(自动清理) |
| max_clean_up_time_sec | 5 | 停止 DAG 时等待步骤清理的最长秒数 |
| max_active_steps | 10 | 单次 DAG 运行内并行步骤上限(0 不限,仅 graph 生效) |
| max_output_size | 1048576 | 每步捕获的 stdout/stderr 字节上限(超限截断) |
| catchup_window | "6h" | 停机补跑窗口(空串禁用补跑) |
关键解读:max_active_steps 与 overlap_policy 是防雪崩的两道闸——前者限制单个 DAG 内并发,后者防止上一轮未结束又叠新轮;max_output_size 防止超大 stdout 撑爆内存,需要完整大输出时应落文件而非依赖捕获。
6.2 base.yaml 注释即文档:可选块速查
base.yaml 注释段(官方内置,实测原文摘引)覆盖的可选配置块:shell(如 "bash -e")、working_dir、dotenv(执行前加载 .env 文件)、timeout_sec/delay_sec/restart_wait_sec、log_dir、queue(跨 DAG 并发组)、defaults(步骤默认值:retry_policy/continue_on/repeat_policy/timeout_sec/signal_on_stop/mail_on_error)、actions(自定义可复用动作)、handler_on、smtp/error_mail/info_mail/wait_mail/mail_on、ssh(远程执行默认:user/host/port/key/strict_host_key/bastion 跳板)、s3(含 MinIO endpoint)、redis(standalone/sentinel/cluster)、llm(openai/anthropic/gemini/openrouter/local)、otel(OpenTelemetry 导出)、registry_auths(镜像仓库凭据)、secrets(env/file/vault 三种密钥来源)、run_config(UI 运行交互控制)。每块的完整字段以本机 cat /var/lib/dagu/base.yaml 为准(注释即官方文档的可执行形态)。
6.3 dagu.env 服务端变量(实测)
| 变量 | 实测值 | 说明 |
|---|---|---|
| DAGU_HOME | /var/lib/dagu | 数据根目录(dags/logs/data 所在) |
| DAGU_HOST | 0.0.0.0 | Web 监听地址;默认 127.0.0.1 仅本机 |
| DAGU_PORT | 8114 | Web 监听端口;默认 8080 |
| PATH | 安装器快照 | DAG 步骤可调用的 CLI 搜索路径 |
⚠️ 注意:重跑官方安装器会重写本文件(DAGU_HOST 还原 127.0.0.1、端口还原 8080),升级后务必复核(实测踩坑记录见《Ubuntu 22.04 安装 Dagu 2.21.0 指南》第七章)。
七、生产配置模板
适用于 4~16GB 内存的单机生产服务器(NFS 无需、外部依赖仅邮件服务器可选),在 base.yaml 追加/覆盖:
# 全局执行与清理基线
type: graph
overlap_policy: skip
log_output: separate
hist_retention_days: 30
max_active_steps: 10
max_output_size: 1048576
max_clean_up_time_sec: 5
catchup_window: "6h"
# 步骤默认重试(幂等任务受益;非幂等任务在 DAG 内单独覆盖为 limit: 0)
defaults:
retry_policy:
limit: 2
interval_sec: 5
backoff: true
max_interval_sec: 60
# 日志与队列(可选)
# log_dir: /var/log/dagu
# queue: default
配套 dagu.env(服务端):
DAGU_HOME=/var/lib/dagu
DAGU_HOST=0.0.0.0
DAGU_PORT=8114
场景说明:上述模板面向「数十个定时脚本、单步秒级~分钟级、失败需告警」的典型运维自动化场景;hist_retention_days 按磁盘余量调整(实测单次运行日志约几十 KB,30 天规模可控);重试默认开启指数退避是为抖动型外部依赖(HTTP/数据库)设计,纯本地脚本可改 interval_sec 固定间隔。
八、常见问题(FAQ)
Q1:YAML 报 mapping value is not allowed in this context?
值里含冒号未加引号。实测原始报错(description 值含冒号):
Error: Validation failed for /var/lib/dagu/dags/c1-retry-demo.yaml
- [1:14] mapping value is not allowed in this context
> 1 | description: C1 field test: deps / retry / env / output passing
^
定位精确到「行:列」([1:14]),把值用双引号包裹即可。run: 里的命令串同理(如 run: 'echo "ALERT: xxx"')。写完先 dagu validate <文件> 再触发。
Q2:文件里写错导致服务端报什么?
调度器实时监听文件,实测日志出现 level=ERROR msg="DAG load failed" err="[1:14] mapping value is not allowed...",修复保存后日志出现 msg="DAG added/updated",无需重启服务。巡检时 journalctl -u dagu | grep "DAG load failed" 可发现所有加载失败的工作流。
Q3:${VAR} 引用没生效/被原样输出?
区分两族语法:Dagu 内部引用是 ${params.x}、${env.X}、${context.paths.artifacts_dir}(带命名空间);shell 变量是 $APP_ENV(env: 定义的直接展开)。混用(如 shell 里写 ${APP_ENV} 带花括号)在多数 shell 下也能展开,但跨 shell 兼容性以 $VAR 写法最稳。
Q4:dry-run 成功、真实执行失败?
dagu dry 不真正执行命令(模拟成功),只验证 DAG 结构。真实行为以 dagu start 为准;排障先看步骤 stderr($DAGU_HOME/logs/<DAG>/dag-run_*/run_*/<step>.*.err)与 DAG 级日志中的 Step execution failed; retrying / error: exit status N 记录。
Q5:改了 base.yaml 没生效?
base.yaml 热加载(官方注释确认);若通过 dagu.env 改的是服务端变量则必须 systemctl restart dagu。另注意优先级:DAG 文件内同名键覆盖 base.yaml 全局值,确认没有在 DAG 里无意覆盖。
Q6:CLI 报找不到刚建的 DAG?
CLI 未带 DAGU_HOME 时操作的是 ~/.config/dagu/dags(实测日志:dir=/root/.config/dagu/dags)。统一 export DAGU_HOME=/var/lib/dagu。
九、参考链接
- 调度与执行控制(官方):https://docs.dagu.sh/writing-workflows/scheduling
- 工作流编写总览:https://docs.dagu.sh/writing-workflows/
- 子工作流与并行:https://docs.dagu.sh/writing-workflows/sub-dags
- 通知与 Webhook(官方):https://docs.dagu.sh/web-ui/notifications
- 本机权威参考:
cat /var/lib/dagu/base.yaml(内置全字段注释)与dagu schema dag - 本站安装篇:《Ubuntu 22.04 安装 Dagu 2.21.0 指南》
- 本站运维篇:《Dagu 日常运维手册》