diff --git a/.vitepress/config.js b/.vitepress/config.js index bfa6599..525baed 100644 --- a/.vitepress/config.js +++ b/.vitepress/config.js @@ -122,6 +122,7 @@ const fullSidebar = [ collapsed: true, items: [ { text: "Cockpit", link: "/web-ui/cockpit" }, + { text: "Documents", link: "/web-ui/documents" }, { text: "Workspaces", link: "/web-ui/workspaces" }, { text: "Profiles", link: "/web-ui/profiles" }, { text: "DAG Secret Refs", link: "/web-ui/secrets" }, diff --git a/[page].md b/[page].md index 39d49de..f589f9d 100644 --- a/[page].md +++ b/[page].md @@ -133,6 +133,10 @@ Want to explore without installing anything? Open the [live demo](https://dagu-d

See every run

Use the Web UI to inspect live status, read step logs, review history, retry failures, and edit workflow YAML.

+
+

Keep runbooks with workflows

+

Write Markdown, preview Mermaid diagrams, organize nested documents, search their contents, and synchronize them through Git.

+

Make jobs reliable

Add dependencies, schedules, retries, timeouts, approvals, notifications, and artifacts in the workflow file.

@@ -164,6 +168,10 @@ Want to explore without installing anything? Open the [live demo](https://dagu-d

Workflow examples

Start from practical YAML for scripts, data jobs, containers, and operations.

+
+

Documents and runbooks

+

Keep operational Markdown, diagrams, and troubleshooting guides next to the workflows they explain.

+

Core concepts

Learn how steps, dependencies, parameters, runs, and schedules fit together.

diff --git a/getting-started/cli.md b/getting-started/cli.md index 6ee5463..691e0bb 100644 --- a/getting-started/cli.md +++ b/getting-started/cli.md @@ -866,6 +866,7 @@ Provide either an item ID or `--all`, not both. ```bash dagu sync publish my-dag -m "Update dag" +dagu sync publish docs/operations/runbook -m "Update runbook" dagu sync publish skills/review -m "Update review skill" dagu sync publish --all -m "Batch update" dagu sync publish my-dag --force -m "Overwrite remote" @@ -944,6 +945,7 @@ Provide either an item ID or `--all-missing`, not both. Untracked items cannot b ```bash dagu sync delete my-dag -m "Remove old dag" +dagu sync delete docs/operations/runbook -m "Remove old runbook" dagu sync delete my-dag --force -m "Remove despite modifications" dagu sync delete --all-missing -m "Clean up missing" dagu sync delete my-dag --dry-run @@ -968,6 +970,7 @@ Both source and destination must be of the same kind. ```bash dagu sync mv old-dag new-dag -m "Rename workflow" +dagu sync mv docs/operations/runbook docs/operations/deploy -m "Rename runbook" dagu sync mv old-dag new-dag --force -m "Move despite conflict" dagu sync mv old-dag new-dag --dry-run ``` diff --git a/overview/web-ui.md b/overview/web-ui.md index 19a2b28..268a277 100644 --- a/overview/web-ui.md +++ b/overview/web-ui.md @@ -1,6 +1,6 @@ # Web UI -Use Dagu's web UI to run workflows, inspect results, edit DAGs, review logs, and manage the server from a browser. +Use Dagu's web UI to run workflows, inspect results, edit DAGs, maintain Markdown documents, review logs, and manage the server from a browser. ## Start the UI @@ -21,18 +21,19 @@ dagu start-all --host 0.0.0.0 --port 9000 Dagu's UI is organized around a few everyday jobs: - **Cockpit** for a live board of recent runs +- **Documents** for Markdown runbooks, Mermaid diagrams, and operational notes - **Dashboard** for recent activity and trends - **Definitions** for the list of workflows - **Run details** for human tasks, approvals, outputs, artifacts, logs, and retries - **Notifications** for Slack, email, Telegram, and webhook routing - **Incidents** for PagerDuty and SolarWinds Incident Response routing - **Profiles** for runtime variables and secrets selected when a run starts -- **Search** for finding workflows quickly +- **Search** for finding workflows and document content quickly - **System Status** for scheduler, coordinator, worker, and resource health ## Workspace Selector -The workspace selector sits at the top of the navigation and affects workspace-aware pages such as Cockpit, Dashboard, Definitions, Runs, Search, and Design. +The workspace selector sits at the top of the navigation and affects workspace-aware pages such as Cockpit, Documents, Dashboard, Definitions, Runs, Search, and Design. ![Workspace selector](/web-ui-workspace-selector-demo.png) @@ -59,6 +60,24 @@ Use it when you want to: See [Cockpit](/web-ui/cockpit) for the dedicated guide. +## Documents + +Documents gives runbooks and workflow notes a first-class home in Dagu. + +![Documents editor](/documents.png) + +Use it to: + +- organize Markdown files in a nested tree +- work across several documents with tabs +- edit and preview Markdown, including Mermaid diagrams +- navigate long documents from their heading outline +- search file names and contents +- keep documents scoped to a workspace +- publish and pull documents with Git Sync + +Unsaved drafts are kept in browser storage, and the editor reports external changes before they can overwrite local work. See [Documents](/web-ui/documents) for file operations, workspace behavior, storage configuration, runtime paths, and Git Sync. + ## Dashboard The Dashboard gives you a broader operations view than Cockpit. @@ -197,6 +216,7 @@ Search helps when you know roughly what you need but not exactly where it lives. You can search: - **DAGs** for workflow definitions +- **Documents** for Markdown files and matching lines ## Profiles & Secrets @@ -310,6 +330,7 @@ ui: - [Workspaces](/web-ui/workspaces) - [Cockpit](/web-ui/cockpit) +- [Documents](/web-ui/documents) - [Profiles and profile-owned secrets](/web-ui/profiles) - [Notifications](/web-ui/notifications) - [Incident Routing](/web-ui/incidents) diff --git a/public/_redirects b/public/_redirects index fbd296c..7705b79 100644 --- a/public/_redirects +++ b/public/_redirects @@ -54,8 +54,8 @@ /features/data-flow/ /writing-workflows/data-flow 301 /features/distributed-execution /server-admin/distributed/ 301 /features/distributed-execution/ /server-admin/distributed/ 301 -/features/documents /overview/web-ui 301 -/features/documents/ /overview/web-ui 301 +/features/documents /web-ui/documents 301 +/features/documents/ /web-ui/documents 301 /features/email-notifications /writing-workflows/email-notifications 301 /features/email-notifications/ /writing-workflows/email-notifications 301 /features/exec /migration/from-cron 301 @@ -128,8 +128,6 @@ /step-types/harness /step-types/harness/ 301 /server-admin/mcp /mcp/ 301 /server-admin/mcp/ /mcp/ 301 -/web-ui/documents /overview/web-ui 301 -/web-ui/documents/ /overview/web-ui 301 # Earlier guide hierarchy /github-integration /dagu-actions/official/github-cli 301 diff --git a/public/documents.png b/public/documents.png new file mode 100644 index 0000000..065e8c8 Binary files /dev/null and b/public/documents.png differ diff --git a/server-admin/configuration.md b/server-admin/configuration.md index de4470b..9481f53 100644 --- a/server-admin/configuration.md +++ b/server-admin/configuration.md @@ -56,6 +56,7 @@ auth: paths: dags_dir: /opt/dagu/dags + docs_dir: /opt/dagu/dags/docs log_dir: /var/log/dagu data_dir: /var/lib/dagu/data dag_state_dir: /var/lib/dagu/data/dag-state @@ -69,6 +70,7 @@ Configuration fields can be overridden with `DAGU_` environment variables. Neste export DAGU_HOST=0.0.0.0 export DAGU_PORT=8080 export DAGU_DAGS_DIR=/opt/dagu/dags +export DAGU_DOCS_DIR=/opt/dagu/dags/docs export DAGU_DAG_DISCOVERY_RECURSIVE=true export DAGU_DATA_DIR=/var/lib/dagu/data export DAGU_DAG_STATE_DIR=/var/lib/dagu/data/dag-state @@ -84,6 +86,7 @@ Common examples: | `DAGU_PORT` | `port` | Web UI port | | `DAGU_PUBLIC_URL` | `public_url` | External URL used in generated links | | `DAGU_DAGS_DIR` | `paths.dags_dir` | DAG definition directory | +| `DAGU_DOCS_DIR` | `paths.docs_dir` | Markdown document directory | | `DAGU_DAG_DISCOVERY_RECURSIVE` | `dag_discovery.recursive` | Discover DAG definitions in subdirectories | | `DAGU_DATA_DIR` | `paths.data_dir` | Data directory used by derived stores | | `DAGU_LOG_DIR` | `paths.log_dir` | Log directory | @@ -127,6 +130,7 @@ Typical layout: |-- config.yaml |-- base.yaml |-- dags/ +| `-- docs/ |-- logs/ `-- data/ |-- artifacts/ @@ -145,6 +149,7 @@ Most persistent runtime data is stored under `paths.data_dir` by default. | Config field | Default | Purpose | | --- | --- | --- | | `paths.dags_dir` | `~/.config/dagu/dags` | DAG definitions | +| `paths.docs_dir` | `{dags_dir}/docs` | Markdown documents and runbooks | | `paths.log_dir` | `~/.local/share/dagu/logs` | DAG logs | | `paths.data_dir` | `~/.local/share/dagu/data` | Base directory for runtime data | | `paths.tools_dir` | `{data_dir}/tools` | Managed DAG tool cache | @@ -158,6 +163,35 @@ Most persistent runtime data is stored under `paths.data_dir` by default. | `paths.contexts_dir` | `{data_dir}/contexts` | CLI contexts | | `paths.workspaces_dir` | `{data_dir}/workspaces` | Web UI workspaces | +## Documents Directory + +`paths.docs_dir` is the storage root for Markdown files managed by the Documents Web UI and Git Sync: + +```yaml +paths: + dags_dir: /opt/dagu/dags + docs_dir: /srv/dagu/documents +``` + +The equivalent environment variable is: + +```bash +export DAGU_DOCS_DIR=/srv/dagu/documents +``` + +When `paths.docs_dir` is not configured, Dagu uses `/docs`. Default-workspace documents live directly in that directory. Named workspaces use a directory named after the workspace: + +```text +/srv/dagu/documents/ +|-- shared-runbook.md +`-- finance/ + `-- month-end-close.md +``` + +`shared-runbook.md` belongs to Default. The second path is owned by the `finance` workspace when that workspace exists. Treat the document root and workspace records as related state when designing backups. Dagu moves the matching document directory when a workspace is renamed and blocks workspace deletion until its documents are removed. + +Each workflow run also receives a per-DAG document path as `${context.paths.docs_dir}` and `DAG_DOCS_DIR`. See [Documents](/web-ui/documents) and [Runtime Context and Variables](/writing-workflows/runtime-variables#documents-directory-context-paths-docs-dir). + ## Recursive DAG Discovery By default, Dagu discovers DAG definitions only at the top level of @@ -240,3 +274,4 @@ Do not put `paths`, `auth`, `coordinator`, `worker`, or other server process set - [Queue Configuration](/server-admin/queues) - [Distributed Execution](/server-admin/distributed/) - [Persistent State](/writing-workflows/persistent-state) +- [Documents](/web-ui/documents) diff --git a/server-admin/deployment/multi-environment.md b/server-admin/deployment/multi-environment.md index 4819b94..71e4000 100644 --- a/server-admin/deployment/multi-environment.md +++ b/server-admin/deployment/multi-environment.md @@ -1,6 +1,6 @@ # Multi-Environment Deployments -Run a separate Dagu deployment for each environment when development, staging, and production must have independent execution boundaries. Each deployment can synchronize reviewed workflow definitions from Git while keeping its scheduler, workers, storage, credentials, and runtime configuration separate. +Run a separate Dagu deployment for each environment when development, staging, and production must have independent execution boundaries. Each deployment can synchronize reviewed workflows and documents from Git while keeping its scheduler, workers, storage, credentials, and runtime configuration separate. ::: warning Do Not Use Workspaces as Environments [Workspaces](/web-ui/workspaces) organize and authorize workflows inside one Dagu installation. They do not create separate schedulers, local execution environments, coordinators, workers, queues, storage, or Git Sync configurations. @@ -32,17 +32,17 @@ Do not mount the same writable data directory into independent environments. Sha ## Promote Workflows with Git Sync -[Git Sync](/server-admin/git-sync) distributes DAG definitions from a repository. Use a branch promotion workflow so each deployment advances only after the workflow version has passed the preceding environment. +[Git Sync](/server-admin/git-sync) distributes DAG definitions, Markdown documents, and workflow-authoring skills from a repository. Use a branch promotion workflow so each deployment advances only after the repository version has passed the preceding environment. A typical flow is: -1. Author and validate a workflow in development. +1. Author and validate a workflow or its operational documents in development. 2. Review the change in Git. 3. Promote the reviewed commit to the branch tracked by staging. 4. Validate the workflow and its integrations in staging. 5. Promote the approved commit to the branch tracked by production. -Configure each deployed environment to track its own branch. Staging and production should normally be read-only so workflow edits cannot publish directly from those installations. +Configure each deployed environment to track its own branch. Staging and production should normally be read-only so workflow and document edits cannot publish directly from those installations. ```yaml # Staging config.yaml diff --git a/server-admin/git-sync.md b/server-admin/git-sync.md index 4f9dab6..bb798d0 100644 --- a/server-admin/git-sync.md +++ b/server-admin/git-sync.md @@ -1,14 +1,17 @@ # Git Sync -Git Sync keeps Dagu workflows and workflow-authoring skill files aligned with a Git repository. +Git Sync keeps Dagu workflows, Markdown documents, and workflow-authoring skill files aligned with a Git repository. ## What It Syncs Git Sync can track: - DAG files +- Markdown documents - skills +DAG files live at the configured repository root, documents live under `docs/`, and skills live under `skills/`. Pulling a repository routes each kind to its configured local storage directory. + ## Tracked Items And IDs Git Sync refers to each tracked file by an `itemId`. You will see that term in the CLI and REST API. @@ -17,6 +20,7 @@ Git Sync refers to each tracked file by an `itemId`. You will see that term in t |---|---|---| | `my-dag.yaml` | `my-dag` | `dag` | | `subdir/report.yml` | `subdir/report` | `dag` | +| `docs/operations/runbook.md` | `docs/operations/runbook` | `doc` | | `skills/review/SKILL.md` | `skills/review/SKILL` | `skill` | ## Basic Configuration @@ -115,6 +119,7 @@ dagu sync pull ```bash dagu sync publish my-dag -m "Update workflow" +dagu sync publish docs/operations/runbook -m "Update operations runbook" dagu sync publish skills/review -m "Update review skill" dagu sync publish --all -m "Batch update" ``` @@ -137,6 +142,7 @@ dagu sync cleanup ```bash dagu sync delete my-dag -m "Remove old workflow" dagu sync mv old-dag new-dag -m "Rename workflow" +dagu sync mv docs/operations/runbook docs/operations/deploy -m "Rename runbook" ``` ## REST API @@ -173,6 +179,7 @@ Write operations are blocked when Git Sync is configured as read-only (`push_ena ## Operational Notes - Manage Git Sync through the UI, CLI, or API rather than editing its internal state directly. +- Documents edited in the Web UI appear as `doc` items in Git Sync status, diff, publish, discard, delete, and move operations. - Pull before publishing when multiple people or systems may change the same repository. - Use clear commit messages because Git Sync publishes normal Git commits. - For staging and production, prefer read-only Git Sync configurations and promote reviewed workflow versions between environment branches. See [Multi-Environment Deployments](/server-admin/deployment/multi-environment). @@ -180,4 +187,5 @@ Write operations are blocked when Git Sync is configured as read-only (`push_ena ## Related Pages - [Server Administration](/server-admin/) +- [Documents](/web-ui/documents) - [Multi-Environment Deployments](/server-admin/deployment/multi-environment) diff --git a/server-admin/index.md b/server-admin/index.md index 56dd7c5..63a712a 100644 --- a/server-admin/index.md +++ b/server-admin/index.md @@ -42,6 +42,7 @@ auth: paths: dags_dir: /opt/dagu/workflows + docs_dir: /opt/dagu/workflows/docs log_dir: /var/log/dagu ``` @@ -60,6 +61,7 @@ docker run -d \ **[Configuration](/server-admin/configuration)** - Config file, environment variables, and precedence - `DAGU_HOME` and path defaults +- Documents and runbook storage - Persistent state directory configuration **[Server Configuration](/server-admin/server)** @@ -150,6 +152,7 @@ export DAGU_PORT=8080 # Paths export DAGU_DAGS_DIR=/opt/workflows +export DAGU_DOCS_DIR=/opt/workflows/docs export DAGU_LOG_DIR=/var/log/dagu # Auth @@ -164,6 +167,7 @@ dagu start-all - [Set up authentication](/server-admin/server#authentication) for production - [Understand configuration precedence](/server-admin/configuration) before mixing flags, environment variables, and `config.yaml` - [Configure base defaults](/server-admin/base-config) for shared DAG settings +- [Configure Documents](/web-ui/documents) for Markdown runbooks and Git Sync - [Configure monitoring](/server-admin/operations#monitoring) for visibility - [Set up distributed execution](/server-admin/distributed/) for scaling - [Review all options](/server-admin/reference) for fine-tuning diff --git a/server-admin/reference.md b/server-admin/reference.md index cf743c5..4ee67ef 100644 --- a/server-admin/reference.md +++ b/server-admin/reference.md @@ -56,6 +56,7 @@ sse: # Directories (must be under "paths" key) paths: dags_dir: "~/.config/dagu/dags" + docs_dir: "" # Auto: {dags_dir}/docs alt_dags_dir: "" # Additional read-only DAG directories log_dir: "~/.local/share/dagu/logs" data_dir: "~/.local/share/dagu/data" @@ -320,6 +321,7 @@ All options support `DAGU_` prefix. - `DAGU_HOME` - Set all directories to this path (can be overridden by `--dagu-home` flag) - `DAGU_DAGS_DIR` - DAG definitions - `DAGU_DAGS` - Alternative to `DAGU_DAGS_DIR` +- `DAGU_DOCS_DIR` - Markdown documents and runbooks (default: `{dags_dir}/docs`) - `DAGU_ALT_DAGS_DIR` - Additional read-only DAG directories - `DAGU_LOG_DIR` - Log files - `DAGU_DATA_DIR` - Application data @@ -771,6 +773,7 @@ peer: ### Auto-generated Paths When not specified, these paths are automatically derived: +- `paths.docs_dir`: `{paths.dags_dir}/docs` - Stores Markdown documents and runbooks - `paths.artifact_dir`: `{paths.data_dir}/artifacts` - Stores DAG run artifacts - `paths.tools_dir`: `{paths.data_dir}/tools` - Stores managed DAG tool cache, locks, manifests, and shims - `paths.dag_state_dir`: `{paths.data_dir}/dag-state` - Stores persistent DAG state values diff --git a/web-ui/api.md b/web-ui/api.md index 3305c76..768cada 100644 --- a/web-ui/api.md +++ b/web-ui/api.md @@ -3335,6 +3335,51 @@ Retrieves information about connected workers in the distributed execution syste } ``` +## Documents Endpoints + +Documents endpoints accept optional `workspace` and `remoteNode` query parameters. Document paths are relative to the selected workspace and omit the `.md` extension. All authenticated users can list, read, and search documents they can access. Mutations require `permissions.write_dags` and a write-capable workspace role. + +| Method | Endpoint | Description | +| --- | --- | --- | +| `GET` | `/api/v1/docs` | List the document tree, or use `flat=true` for a flat list. | +| `POST` | `/api/v1/docs` | Create a Markdown document. | +| `GET` | `/api/v1/docs/search?q=...` | Search document content. | +| `GET` | `/api/v1/docs/doc?path=...` | Read one document. | +| `PATCH` | `/api/v1/docs/doc?path=...` | Replace one document's content. | +| `DELETE` | `/api/v1/docs/doc?path=...` | Delete one document. | +| `POST` | `/api/v1/docs/doc/rename?path=...` | Rename or move a document or directory. | +| `POST` | `/api/v1/docs/delete-batch` | Delete several documents or directories. | + +Create a document in the `operations` directory of the default workspace: + +```bash +curl -X POST "http://localhost:8080/api/v1/docs?workspace=default" \ + -H "Content-Type: application/json" \ + -d '{"id":"operations/runbook","content":"# Operations runbook\n"}' +``` + +Read or update the same document: + +```bash +curl "http://localhost:8080/api/v1/docs/doc?workspace=default&path=operations%2Frunbook" + +curl -X PATCH "http://localhost:8080/api/v1/docs/doc?workspace=default&path=operations%2Frunbook" \ + -H "Content-Type: application/json" \ + -d '{"content":"# Updated operations runbook\n"}' +``` + +Rename and batch-delete requests use `newPath` and `paths` respectively: + +```json +{"newPath":"operations/deploy"} +``` + +```json +{"paths":["operations/deploy","legacy"]} +``` + +See [Documents](/web-ui/documents) for Web UI behavior, workspace ownership, storage, and Git Sync. + ## Git Sync Endpoints All sync endpoints accept an optional `remoteNode` query parameter. diff --git a/web-ui/documents.md b/web-ui/documents.md new file mode 100644 index 0000000..449cf17 --- /dev/null +++ b/web-ui/documents.md @@ -0,0 +1,135 @@ +# Documents + +Documents keeps operational knowledge next to the workflows it explains. Use the Web UI to write Markdown runbooks, troubleshooting notes, handoff guides, and diagrams without leaving Dagu. + +![Documents editor with file tree, Markdown preview, and outline](/documents.png) + +## What You Can Do + +- organize Markdown files in a nested file tree +- create, rename, move, and delete files and folders +- keep several documents open in tabs +- edit Markdown and preview the rendered result side by side +- render Mermaid diagrams in the preview +- jump through long documents from the generated outline +- search document names and contents +- scope documents to the default or a named workspace +- synchronize documents with a Git repository through [Git Sync](/server-admin/git-sync) + +## Browse And Organize Documents + +Open **Documents** from the navigation. The sidebar shows the document tree for the selected workspace. + +Use the tree actions to: + +- create a document or folder +- rename an item +- drag an item into another folder +- select several items for deletion +- expand or collapse nested folders + +Document names use the `.md` extension. Dagu adds it when a new document name omits the extension. A file and a directory cannot have the same path identity, so names such as `runbook.md` and `runbook/` cannot exist side by side. + +Moving documents between workspaces is not supported. Select the destination workspace first and create or synchronize the document there. + +## Edit And Preview Markdown + +Open a document to add it as a tab. The editor provides: + +- **Edit** and **Preview** modes +- standard Markdown rendering +- Mermaid diagram rendering +- an outline generated from headings +- `Ctrl+S` or `Cmd+S` to save + +Dagu keeps unsaved content in browser storage so an accidental navigation or reload does not immediately lose the draft. Drafts are separated by authenticated user, remote node, and workspace. Saving or discarding the draft clears the stored copy. + +An open document with unsaved changes must be saved before it can be renamed or moved. This keeps the editor buffer attached to the correct file. + +When another user or Git Sync changes an open document, the editor reports the external update instead of silently overwriting local edits. Documents receives live update events when available and falls back to periodic refreshes. + +## Workspace Scoping + +Documents follows the workspace selector: + +| Selection | Documents shown | +| --- | --- | +| **All workspaces** | Documents from every workspace the account can access. This aggregate view is for browsing and search. | +| **Default** | Documents that are not assigned to a named workspace. | +| **Named workspace** | Only documents owned by that workspace. | + +Select **Default** or a specific named workspace before creating, renaming, moving, or deleting content. + +On disk, Dagu stores default documents directly under `paths.docs_dir` and named-workspace documents under a workspace directory: + +```text +/ +|-- operations/ +| `-- runbook.md +`-- platform/ + `-- incident-response.md +``` + +In this example, `operations/runbook.md` belongs to **Default**, while `platform/incident-response.md` belongs to the `platform` workspace. + +Renaming a workspace moves its document tree to the new workspace name. A workspace cannot be deleted while it still contains documents; move or remove those documents first. + +See [Workspaces](/web-ui/workspaces) for access rules and lifecycle behavior. + +## Search + +The Documents sidebar filters the current tree by file name and document content. Dagu's global **Search** page also returns matching documents and the lines containing the query, subject to workspace access. + +## Storage Configuration + +The document root is configured with `paths.docs_dir`: + +```yaml +paths: + dags_dir: /opt/dagu/dags + docs_dir: /opt/dagu/dags/docs +``` + +The equivalent process configuration variable is `DAGU_DOCS_DIR`. When no value is configured, Dagu uses `/docs`. + +See [Configuration](/server-admin/configuration#documents-directory) for deployment and storage details. + +## Use Documents From A Workflow + +Each run receives the document directory for its DAG as `${context.paths.docs_dir}`. Processes receive the same path as `DAG_DOCS_DIR`. + +```yaml +steps: + - id: print_runbook + run: cat "${context.paths.docs_dir}/runbook.md" +``` + +For a default-workspace DAG named `operations`, the path resolves to `/operations`. For the same DAG in the `platform` workspace, it resolves to `/platform/operations`. + +`DAGU_DOCS_DIR` configures the server-wide document root. `DAG_DOCS_DIR` is the per-DAG path projected into a running step. + +See [Runtime Context and Variables](/writing-workflows/runtime-variables#documents-directory-context-paths-docs-dir) for the full runtime contract. + +## Git Sync + +Git Sync tracks documents under `docs/` in the repository. For example, the local document `operations/runbook.md` is represented as: + +```text +repository path: docs/operations/runbook.md +itemId: docs/operations/runbook +kind: doc +``` + +Pulling writes repository documents into the configured document root. Publishing sends Web UI edits back to the repository when Git Sync writes are enabled. See [Git Sync](/server-admin/git-sync) for setup, status, conflicts, and CLI commands. + +## Permissions + +Authenticated users can browse documents in workspaces they are allowed to access. Creating, saving, renaming, moving, and deleting documents requires `permissions.write_dags` and a write-capable role for the selected workspace. + +## Related + +- [Web UI](/overview/web-ui) +- [Workspaces](/web-ui/workspaces) +- [Git Sync](/server-admin/git-sync) +- [Configuration](/server-admin/configuration#documents-directory) +- [Runtime Context and Variables](/writing-workflows/runtime-variables#documents-directory-context-paths-docs-dir) diff --git a/web-ui/workspaces.md b/web-ui/workspaces.md index dd69bd5..16d82e7 100644 --- a/web-ui/workspaces.md +++ b/web-ui/workspaces.md @@ -2,7 +2,7 @@ Workspaces organize workflows and runs inside one Dagu installation. Use them to separate workflows by team, business function, product, or operational responsibility, such as `finance`, `data-platform`, `customer-support`, or `platform-ops`. -Workspaces can also scope access, managed secrets, profile defaults, notifications, and incident routing. +Workspaces can also scope access, documents, managed secrets, profile defaults, notifications, and incident routing. ![Workspace selector](/web-ui-workspace-selector-demo.png) @@ -16,6 +16,7 @@ Use workspaces when you want to: - keep the DAG list focused on one team or business function - review only the runs that belong to a project +- keep runbooks and operational notes with the team that owns them - keep Web UI-managed secrets scoped to the workflows that use them - route notifications to the responsible team's channels - route incidents to the responsible team's PagerDuty or SolarWinds connections @@ -39,13 +40,13 @@ The scheduler loads and evaluates workflows across the deployment regardless of ## Selecting a Workspace -The workspace selector is in the left navigation above the remote node selector. It affects workspace-aware pages such as Cockpit, Dashboard, Definitions, Runs, Search, Design, Notifications, and Incident Routing. +The workspace selector is in the left navigation above the remote node selector. It affects workspace-aware pages such as Cockpit, Documents, Dashboard, Definitions, Runs, Search, Design, Notifications, and Incident Routing. | Selection | What You See | | --- | --- | -| **All workspaces** | Everything your account can access. | -| **Default** | Workflows that do not have a workspace label. | -| **Named workspace** | Only workflows and runs for that workspace. | +| **All workspaces** | Everything your account can access across workflows, runs, and documents. Document changes are disabled in this aggregate view. | +| **Default** | Workflows without a workspace label and documents outside named-workspace directories. | +| **Named workspace** | Only workflows, runs, and documents for that workspace. | The selector stays on your last choice in the browser, so switching from `finance` to Runs keeps the same focus. @@ -77,6 +78,21 @@ After saving the DAG, select `finance` in the Web UI to see it with the matching When you start or enqueue a workflow from Cockpit while a named workspace is selected, Dagu adds the matching workspace label to the run so it appears in the same workspace view. +## Documents in Workspaces + +The [Documents](/web-ui/documents) page uses the same workspace selector as workflows and runs. Default documents live directly under `paths.docs_dir`; documents in a named workspace live under `//`. + +```text +/ +|-- shared-runbook.md # Default +`-- finance/ + `-- month-end-close.md # finance workspace +``` + +Workspace access filters the document tree, content search, and global search results. **All workspaces** combines the documents the current account can access for browsing and search. Select **Default** or one named workspace before creating, renaming, moving, or deleting a document. + +Documents cannot be dragged across workspace boundaries. Renaming a workspace moves its document directory to the new name. Deletion is blocked while the workspace still contains documents, which prevents them from losing their workspace ownership. + ## Secrets in Workspaces The **DAG Secret Refs** tab on the **Profiles & Secrets** page supports global and workspace scopes. A Dagu-managed secret with ref `database/password` in `finance` is different from a secret with the same ref in `data-platform`. @@ -150,13 +166,16 @@ See [User Management](/server-admin/authentication/user-management) and [API Key ## Deleting a Workspace -Deleting a workspace removes it from the selector. It does not delete DAG files, run history, users, or API keys. +Deleting a workspace removes it from the selector. It does not delete DAG files, documents, run history, users, or API keys. Before deleting a workspace, check whether: +- its Documents tree is empty; move or remove its documents first - any DAGs still use `workspace=` - users or API keys are scoped to that workspace +Dagu rejects the deletion while documents remain in the workspace. This keeps those files from becoming visible as default documents after their workspace disappears. + After deletion, update affected DAG labels and access grants so future work stays easy to find. ## API Access @@ -175,6 +194,7 @@ For request and response details, see [REST API](/web-ui/api). ## Related - [Cockpit](/web-ui/cockpit) +- [Documents](/web-ui/documents) - [Notifications](/web-ui/notifications) - [Incident Routing](/web-ui/incidents) - [DAG Secret Refs](/web-ui/secrets) diff --git a/writing-workflows/runtime-variables.md b/writing-workflows/runtime-variables.md index ffa2b03..8791f46 100644 --- a/writing-workflows/runtime-variables.md +++ b/writing-workflows/runtime-variables.md @@ -27,6 +27,7 @@ Use `${context.*}` references in value-resolved fields such as `run`, `with`, `e | `${context.trigger.actor}` | Runs started by an attributable actor | None | | `${context.paths.log_file}` | All steps and handlers | `DAG_RUN_LOG_FILE` | | `${context.paths.work_dir}` | When a per-run work directory is available | `DAG_RUN_WORK_DIR` | +| `${context.paths.docs_dir}` | All steps and handlers | `DAG_DOCS_DIR` | | `${context.paths.artifacts_dir}` | When artifact storage is active | `DAG_RUN_ARTIFACTS_DIR` | | `${context.paths.step_stdout_file}` | Current executable step after stdout is assigned | `DAG_RUN_STEP_STDOUT_FILE` | | `${context.paths.step_stderr_file}` | Current executable step after stderr is assigned | `DAG_RUN_STEP_STDERR_FILE` | @@ -66,6 +67,7 @@ Values are refreshed for each step, so `DAG_RUN_STEP_NAME`, `DAG_RUN_STEP_STDOUT | `DAG_WAITING_STEPS` | Wait handler only | Comma-separated list of step names currently waiting for human-task completion or approval. | `release_review,security_review` | | `PWD` | Current step only | Working directory for the step. Defaults to DAG's `working_dir` or the DAG file's directory. | `/home/user/project` | | `DAG_RUN_WORK_DIR` | All steps & handlers | Absolute path to the per-DAG-run working directory. Each run gets its own isolated directory. In local mode, this is `/work/`. In shared-nothing (distributed) mode, this is a temporary directory under the system temp dir. Not set during dry runs. | `/data/dagu/dag-runs/daily-backup/dag-run_20241012_040000Z_c1f4b2/work` | +| `DAG_DOCS_DIR` | All steps & handlers | Absolute path to the current DAG's document directory. Named-workspace DAGs include the workspace directory. | `/opt/dagu/dags/docs/platform/daily-backup` | | `DAG_RUN_ARTIFACTS_DIR` | All steps & handlers when artifact storage is active | Absolute path to the per-DAG-run artifact directory, or a worker-local staging directory in shared-nothing mode. Artifact storage is active when enabled explicitly or auto-enabled by `${context.paths.artifacts_dir}` references, artifact actions, or artifact stream outputs. | `/data/dagu/artifacts/daily-backup/dag-run_20241012_040000Z_c1f4b2` | | `DAG_PARAMS_JSON` | All steps & handlers | JSON string containing the resolved parameter map. Resolved DAG params are serialized as strings; if the run was started with raw JSON parameters, the original payload is preserved. Not set when the DAG has no resolved parameters. | `{"ENVIRONMENT":"prod","batchSize":"1000"}` | | `DAG_PUSHBACK` | Steps re-executed after approval push-back only | JSON string containing the current push-back iteration, latest inputs, authenticated actor, server timestamp, and chronological history. Not set on the initial execution. | `{"iteration":2,"by":"reviewer","at":"2026-04-26T06:18:43Z","inputs":{"FEEDBACK":"Tighten summary"},"history":[...]}` | @@ -122,6 +124,29 @@ steps: - build ``` +## Documents Directory (`${context.paths.docs_dir}`) + +`${context.paths.docs_dir}` points to the document directory associated with the current DAG. Processes receive the same path through `DAG_DOCS_DIR`. + +```yaml +steps: + - id: show_runbook + run: cat "${context.paths.docs_dir}/runbook.md" +``` + +The path is derived from the server's `paths.docs_dir` and the DAG identity: + +| DAG scope | Runtime document directory | +| --- | --- | +| Default workspace, DAG `operations` | `/operations` | +| Workspace `platform`, DAG `operations` | `/platform/operations` | + +This directory is shared across runs of the same DAG, unlike `${context.paths.work_dir}` and `${context.paths.artifacts_dir}`, which are run-specific. It is suitable for durable Markdown instructions and other documents managed from the [Documents Web UI](/web-ui/documents). + +`DAGU_DOCS_DIR` is the process configuration variable that overrides the server-wide root. `DAG_DOCS_DIR` is the per-DAG runtime projection supplied to steps and handlers. + +See [Documents](/web-ui/documents) for editing, workspace scoping, and Git Sync, and [Configuration](/server-admin/configuration#documents-directory) for the storage root. + ## Artifacts Directory (`${context.paths.artifacts_dir}`) `${context.paths.artifacts_dir}` is available, and `DAG_RUN_ARTIFACTS_DIR` is set for processes, when the DAG enables artifact storage explicitly: