Dagu
Overview
Dagu is a self-contained workflow and cron orchestration engine. You describe your work as a DAG, a directed acyclic graph of steps, in a single readable YAML file. Dagu runs it on demand or on a schedule, resolving dependencies between steps and handling retries, timeouts, preconditions and lifecycle hooks.
A built-in web UI lets you browse workflows, start and stop runs, watch each step of a run graph in real time, and inspect per-run logs and execution history. A REST API and a full command-line interface drive the same engine from scripts. Dagu needs no database and no message broker and keeps all of its state on the local filesystem, so it starts instantly. It suits cron replacement, data pipelines, backups, batch jobs and edge automation on a single machine.
This SecureAnyCloud image installs the pinned Dagu 2.10.7 single Go binary, running under systemd as dagu start-all (the HTTP server, scheduler and executor in one process). Dagu binds to loopback 127.0.0.1:8080, so its UI and API are never exposed directly. An nginx reverse proxy on port 80 adds a per-VM HTTP Basic Auth gate in front of it.
Dagu's own web UI is unauthenticated by default, so this image closes that gap. nginx requires the admin credential, a unique password generated on the first boot of your VM, for the entire UI and API. An unauthenticated /healthz endpoint stays open for load balancer probes. An example workflow is bundled so the engine has something to run immediately.
What you get:
- Dagu 2.10.7 installed as a single Go binary (
/usr/local/bin/dagu) running as thedagusystemd service (dagu start-all) - The Dagu web UI and REST API on
:80, fronted by nginx with the binary bound to loopback only - Per-VM HTTP Basic Auth (user
admin) protecting the entire UI and API, with a unique password generated on first boot - Dagu bound to
127.0.0.1:8080, so nothing is exposed to the network directly - Dagu's own native basic auth, also enabled on the loopback interface as defence in depth
- An example workflow at
/var/lib/dagu/dags/hello.yamlthat runs on first boot to prove the engine DAGU_HOME=/var/lib/daguholding your workflow definitions (dags/), run logs and statedagu.serviceandnginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Azure Load Balancer health probes - Ubuntu 24.04 LTS base, latest patches, unattended security upgrades enabled
- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size, because Dagu is light on resources.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the UI and API. Also allow 443/tcp if you add TLS. Dagu serves plain HTTP on port 80, so for production terminate TLS in front of it with your own domain and restrict access to trusted IP ranges (see Maintenance).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Dagu by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Select Review + create, then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:dagu-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name dagu \
--image sac1647283583153:dagu-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name dagu --port 80 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
systemctl is-active dagu.service nginx.serviceBoth services report active. Dagu serves its web UI and REST API on the loopback address 127.0.0.1:8080. nginx fronts it on port 80 and adds the per-VM HTTP Basic Auth gate. Nothing binds a public application port directly, so the only way in is through nginx.
Step 5 - Retrieve your web UI password
nginx protects the Dagu UI and API with HTTP Basic Auth. The username is admin. First boot generates a unique password for your VM and writes it to a root-only file:
sudo cat /root/dagu-credentials.txtThe file contains DAGU_USERNAME, DAGU_PASSWORD and the DAGU_URL to open in a browser. nginx stores the password only as a bcrypt hash in /etc/nginx/.dagu.htpasswd, so no plaintext password ships in the image. Store the password somewhere safe.
Step 6 - Confirm the health endpoint
nginx serves an unauthenticated health endpoint for load balancers and probes:
curl -s http://localhost/healthzThe endpoint returns ok. It never requires authentication, so it is safe to use for an Azure Load Balancer health probe.
Step 7 - Confirm the authentication gate
Because first boot sets a password, an unauthenticated request to the UI returns HTTP 401, so nobody reaches Dagu without the password. The command below reads the per-VM password from the credentials file and tests three cases: an unauthenticated request is rejected, a wrong password is rejected, and the correct password authenticates:
PW=$(sudo grep '^DAGU_PASSWORD=' /root/dagu-credentials.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
echo "wrongpw : $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-pw http://127.0.0.1/)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/)"It prints unauth : 401, wrongpw : 401 and authed : 200. The whole UI and API are reachable only with the per-VM password, because Dagu itself is bound to loopback and nginx is the only way in.
Step 8 - Run the bundled example workflow
A Dagu workflow is a YAML file that describes a directed acyclic graph of steps. The image ships an example at /var/lib/dagu/dags/hello.yaml, with two steps (greet, then show_date) and a */30 cron schedule. Run it from the command line and watch the engine execute each step to success:
sudo -u dagu env DAGU_HOME=/var/lib/dagu /usr/local/bin/dagu start /var/lib/dagu/dags/hello.yamlThe engine runs greet, then show_date (which depends on greet), and reports Result: Succeeded. Copy the file and edit it to build your own workflows, or create new ones under /var/lib/dagu/dags/.
Step 9 - Sign in and open the dashboard
Browse to http://<vm-public-ip>/. When your browser prompts for a username and password, enter admin and the password from Step 5.
Dagu opens on the Overview dashboard. It shows a timeline of recent DAG runs with a summary of how many succeeded, failed or were aborted.
Step 10 - Browse your workflows
Open the Workflows page from the left navigation. It lists every DAG under /var/lib/dagu/dags/ with its latest status, the time of its last run, and its schedule and next run time. Action buttons let you start, stop or reload a workflow. The bundled hello workflow appears here with its */30 cron schedule.
Step 11 - Inspect a workflow and its run graph
Click a workflow to open its detail view. The Status tab renders the DAG as a graph, so you can see the dependencies between steps (here, greet leads to show_date). Each node is coloured by the outcome of the latest run.
The Timeline, Outputs and Spec tabs show the run timeline, captured step outputs and the raw YAML definition.
Step 12 - Review execution history
Open the Executions page from the left navigation for a searchable, filterable history of every DAG run across your workflows.
Each row shows the workflow name, the run ID and its status. It also shows what triggered the run (a schedule, a manual start or a retry), the scheduled, queued and started times, the duration, and the worker that executed it.
Step 13 - Review the installed components
Dagu ships as a single static Go binary with a small, predictable filesystem layout. DAGU_HOME=/var/lib/dagu holds your workflow definitions in dags/, run logs in logs/ and engine state in data/:
dagu version ls /usr/local/bin/dagu /etc/dagu/dagu.env /var/lib/dagu/dags/hello.yamlMaintenance
- Password: first boot sets the UI password and stores it as a bcrypt entry in
/etc/nginx/.dagu.htpasswd. To change it, runsudo htpasswd -B /etc/nginx/.dagu.htpasswd admin. Set the same value inDAGU_AUTH_BASIC_PASSWORDin/etc/dagu/dagu.env. Then runsudo systemctl reload nginxandsudo systemctl restart dagu. - Create workflows: add your own
*.yamlDAG files under/var/lib/dagu/dags/. Each file definessteps:with anid:and arun:command, optionaldepends:for ordering, and an optionalschedule:cron expression. Dagu picks them up automatically and they appear on the Workflows page. - Restrict access: Dagu serves plain HTTP on port 80. For production, restrict access to trusted IP ranges in your Network Security Group, and front it with TLS (for example certbot with your own domain) terminating on
:443. - Loopback binding: Dagu is bound to
127.0.0.1:8080(DAGU_HOSTandDAGU_PORTin/etc/dagu/dagu.env), so nginx is the only path in. Do not change the bind address to a public interface. - Scheduling:
dagu start-allruns the scheduler, so any workflow with aschedule:cron expression runs automatically. Configure overlap policy, catch-up and retry behaviour per workflow in its YAML. - Storage: all workflow definitions, run logs and engine state live under
/var/lib/dagu. Back up that directory to protect your workflows and run history. - Security patches: unattended-upgrades stays enabled, so the OS continues to receive security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
Deploy on Azure
Launch Dagu on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Dagu is a self-contained workflow and cron orchestration engine. You describe your work as a DAG, a directed acyclic graph of steps, in a single readable YAML file. Dagu runs it on demand or on a schedule, resolving dependencies between steps and handling retries, timeouts, preconditions and lifecycle hooks.
A built-in web UI lets you browse workflows, start and stop runs, watch each step of a run graph in real time, and inspect per-run logs and execution history. A REST API and a full command-line interface drive the same engine from scripts. Dagu needs no database and no message broker and keeps all of its state on the local filesystem, so it starts instantly. It suits cron replacement, data pipelines, backups, batch jobs and edge automation on a single machine.
This SecureAnyCloud image installs the pinned Dagu 2.10.7 single Go binary, running under systemd as dagu start-all (the HTTP server, scheduler and executor in one process). Dagu binds to loopback 127.0.0.1:8080, so its UI and API are never exposed directly. An nginx reverse proxy on port 80 adds a per-instance HTTP Basic Auth gate in front of it.
Dagu's own web UI is unauthenticated by default, so this image closes that gap. nginx requires the admin credential, a unique password generated on the first boot of your instance, for the entire UI and API. An unauthenticated /healthz endpoint stays open for load balancer probes. Two example workflows are bundled so the engine has something to run immediately.
What you get:
- Dagu 2.10.7 installed as a single Go binary (
/usr/local/bin/dagu) running as thedagusystemd service (dagu start-all) - The Dagu web UI and REST API on
:80, fronted by nginx with the binary bound to loopback only - Per-instance HTTP Basic Auth (user
admin) protecting the entire UI and API, with a unique password generated on first boot - Dagu bound to
127.0.0.1:8080, so nothing is exposed to the network directly - Dagu's own native basic auth, also enabled on the loopback interface as defence in depth
- Example workflows at
/var/lib/dagu/dags/(hello.yamlandetl-pipeline.yaml) so the engine works out of the box DAGU_HOME=/var/lib/daguon a dedicated data volume, holding your workflow definitions (dags/), run logs and statedagu.serviceandnginx.serviceas systemd units, enabled and active- An unauthenticated
/healthzendpoint for Elastic Load Balancing health checks - Ubuntu 24.04 LTS base, fully patched at build time
- 24/7 SecureAnyCloud support
Prerequisites
You need an AWS account, an EC2 key pair in the target region, and a VPC with a public subnet.
m5.large (2 vCPU / 8 GiB RAM) is the recommended instance type, because Dagu is light on resources.
Configure the security group to allow inbound 22/tcp from your management network for SSH and 80/tcp for the web UI and API. Dagu serves plain HTTP on port 80, so for production terminate TLS in front of it with your own domain and restrict access to trusted IP ranges (see Maintenance).
Step 1 - Launch the AMI
Subscribe to the listing in AWS Marketplace and choose Launch.
Pick the Ubuntu 24.04 version and an m5.large instance type. Select your key pair, a public subnet, and a security group that allows 22/tcp (from your IP) and 80/tcp.
Launch the instance and wait for the status checks to pass.
Step 2 - Connect to your instance
Connect over SSH as the default login user for the OS variant you launched. For Ubuntu 24.04, the login user is ubuntu.
ssh -i /path/to/key.pem ubuntu@<instance-public-ip>Step 3 - Confirm the services are running
Dagu and nginx are managed by systemd and come up on boot. Confirm both are active:
systemctl is-active dagu nginxDagu binds only to the loopback interface. Confirm that nothing serves the raw application port to the network:
ss -tln | grep '127.0.0.1:8080'Check the installed Dagu version:
/usr/local/bin/dagu versionStep 4 - Retrieve your unique admin credential
On the first boot of your instance, the image generated a cryptographically random admin password. It wrote the password to a root-only file, together with the URL to open. Read the file with the command below. The command redacts the password, so drop the sed filter to see it:
sudo sed 's/^DAGU_PASSWORD=.*/DAGU_PASSWORD=<redacted - remove this sed filter to reveal>/' /root/dagu-credentials.txtThe file is 0600 root:root, so only an administrator on the instance can read it. The image contains no default or shared password.
Step 5 - Confirm authentication from the command line
Before opening a browser, test the security model from the instance itself. The health endpoint is open, the UI is closed without credentials, and the per-instance password authenticates. The command below reads the password into a shell variable without printing it:
PW=$(sudo grep '^DAGU_PASSWORD=' /root/dagu-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'health (unauthenticated): %{http_code}\n' http://127.0.0.1/healthz
curl -s -o /dev/null -w 'UI without credentials: %{http_code}\n' http://127.0.0.1/
curl -s -o /dev/null -w 'UI with admin password: %{http_code}\n' -u "admin:$PW" http://127.0.0.1/You should see 200 for the health check, 401 for the unauthenticated UI, and 200 once the correct password is supplied.
Step 6 - Sign in to the web UI
Open http://<instance-public-ip>/ in your browser. When nginx prompts for HTTP Basic Auth, sign in with the username admin and the password from Step 4. The dashboard opens on the Timeline, which shows recent runs across all your workflows.
Open Workflows to see every DAG the engine knows about. Each one shows its schedule and last status, with controls to run, stop or refresh it. The image ships with two example workflows.
Select a workflow to see its run graph. Each step is a node, dependencies are edges, and colour shows status. Here the etl-pipeline example fans out from extract to two transform steps and back into a single load, and all steps succeeded.
The History view shows each step's status across every run, with the run graph, timeline and per-step logs a click away.
Step 7 - Run and define workflows
The bundled example workflows live under DAGU_HOME/dags. List them with this command:
ls -1 /var/lib/dagu/dags/Trigger a run from the command line (or press Start in the UI) and watch it succeed:
sudo -u dagu env DAGU_HOME=/var/lib/dagu /usr/local/bin/dagu start /var/lib/dagu/dags/hello.yamlTo create your own workflow, add a YAML file to /var/lib/dagu/dags/. A DAG is a list of steps. Each step has an id, a run command, and an optional depends list naming the steps it waits for. An optional top-level schedule runs the workflow automatically on a cron expression. For example:
schedule: "0 2 * * *"
# run at 02:00 every day steps: - id: backup run: /usr/local/bin/my-backup.sh - id: notify run:
echo "backup finished" depends: backupDagu picks up new and edited files automatically, so the workflow appears in the UI without a restart.
Step 8 - Where Dagu keeps its state
DAGU_HOME=/var/lib/dagu is a dedicated EBS data volume, separate from the OS disk. Your workflow definitions, run logs and execution history survive OS-disk changes, and you can resize the volume independently. Confirm that it is its own filesystem:
findmnt /var/lib/dagu && df -h /var/lib/daguThis volume holds everything under dags/ (definitions), logs/ (per-run logs) and data/ (run state). Back it up with EBS snapshots or AWS Backup.
Maintenance
- Health checks: point an Application Load Balancer target group at
/healthzon port 80. It returns200without authentication, so probes never need the admin credential. - Add TLS for production: Dagu is served over plain HTTP on port 80. For production, put your own domain and certificate in front of nginx, for example with Certbot or by terminating TLS at an ALB. Restrict the security group to trusted IP ranges.
- Rotate the admin password: edit
DAGU_AUTH_BASIC_PASSWORDin/etc/dagu/dagu.env, regenerate the nginx credential withsudo htpasswd -B /etc/nginx/.dagu.htpasswd admin, thensudo systemctl restart dagu nginx. - Service management: restart the services with
sudo systemctl restart daguandsudo systemctl restart nginx. Read their logs withjournalctl -u daguandjournalctl -u nginx.
Support
SecureAnyCloud provides 24/7 technical support for this product by email and live chat at sales@secureanycloud.com.
We help with deployment, reverse-proxy termination with your own domain and TLS certificate, workflow and schedule configuration, and backup planning for your workflow store.
For refund requests, contact support with your AWS account ID and subscription details.
Deploy on AWS
Launch Dagu with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com