Hi, I’m the founder of Watchgoose (https://watchgoose.com), a heartbeat monitor for cron jobs, backups and all kinds of recurring workloads.
I think a lot of people here rely on the email reports but those only cover failures Duplicacy itself notice. If the machine is off, the schedule stops or Duplicacy never starts then nothing is sent. A heartbeat check covers that, Duplicacy pings a URL after each backup and you get an alert when the ping doesnt arrive or reports a failure. Pinging a monitoring service after backups came up here before so below are three setups I tested with Duplicacy CLI 3.3.0 and Web Edition 1.8.3.
Replace https://watchgoose.com/ping/your-check-uuid with your check’s ping URL in all examples. Whichever option you use run one backup by hand afterwards and confirm the check shows as up, a new check only starts watching for missed runs after its first success ping.
How Duplicacy runs the scripts
A few details that matter for monitoring (checked against the 3.3.0 source and in tests):
-
pre-backupruns before the backup,post-backupruns only after a successful backup. If the backup fails (wrong password, storage missing, missing chunk), Duplicacy exits with code 100 andpost-backupdoes not run. - If a
pre-*script exits non-zero, Duplicacy aborts the command with exit code 100. So a ping script must alwaysexit 0or a network hiccup will cancel your backup. A non-zeropost-*script also turns a successful backup into exit code 100. - Scripts receive Duplicacy’s own command line as arguments (for example
/usr/bin/duplicacy -log backup -stats) and inherit its environment and working directory. They get no result or stats. - Skipped files (access errors) are only a warning, the backup still exits 0,
post-backupstill runs, and the Web Edition report says"result":"Success".
Option 1: Web Edition, “Send report to” (no scripts)
On the Backup page, click the backup’s report icon, enter the ping URL and tick Send report on failure. In my tests the box really means “also send on failure”:
- unticked: a report is sent only after succesful backups
- ticked: a report is sent after successful and failed backups
The report is a JSON POST with a result field: "result":"Success", "result":"Error" (the job hit an error), or "result":"Failed" (the job was terminated or an option was invalid). A plain ping URL counts any request as success so the failed report has to be told apart by its content. In Watchgoose, open the check, click Filtering Rules, tick Request body of HTTP requests under Content Filtering, and set:
Failure keywords: "result":"Error","result":"Failed"
Success keywords: "result":"Success"
If no keywords match: Ignore the ping
Now a failed backup alerts right away and a backup that never runs alerts when the period plus grace time passes. The report covers backups only, not check, prune or copy jobs.
Optional - to also measure run time add a pre-backup script (Option 2) in ~/.duplicacy-web/repositories/localhost/<n>/.duplicacy/scripts/, where <n> is the backup’s index. With keyword filtering on send a body with the start ping (curl -d "backup started" .../start) and add backup started as a start keyword, otherwise the empty start ping is ignored.
Option 2: pre-backup and post-backup scripts (CLI or Web Edition)
.duplicacy/scripts/pre-backup:
#!/bin/sh
# Always exit 0: a non-zero exit here makes Duplicacy abort the backup.
curl -fsS -m 10 --retry 3 -o /dev/null \
https://watchgoose.com/ping/your-check-uuid/start || true
exit 0
.duplicacy/scripts/post-backup:
#!/bin/sh
# Runs only after a successful backup.
curl -fsS -m 10 --retry 3 -o /dev/null \
https://watchgoose.com/ping/your-check-uuid || true
exit 0
Make both executable (chmod +x). On Windows use pre-backup.bat and post-backup.bat with curl.exe. Because post-backup doesn’t run after a failure a failed backup shows up as a start without a success and you get alerted once the grace time passes. Set the grace time a bit longer than your longest backup.
Option 3: CLI wrapper script (immediate failure alerts and the log)
For cron or systemd timers this is the most complete setup, it sends /start, runs Duplicacy, then sends the exit code with the last 10,000 bytes of output, so a failure is reported as soon as it happens and the error line is visible in the check’s history.
#!/bin/sh
# duplicacy-watchgoose.sh: run a Duplicacy command and report it.
# Usage: WATCHGOOSE_URL=https://watchgoose.com/ping/your-check-uuid \
# duplicacy-watchgoose.sh backup -stats
DUPLICACY="${DUPLICACY:-duplicacy}"
URL="${WATCHGOOSE_URL:?set WATCHGOOSE_URL to the ping URL of your check}"
LOG=$(mktemp) || exit 1
trap 'rm -f "$LOG"' EXIT
curl -fsS -m 10 --retry 3 -o /dev/null "$URL/start" || true
"$DUPLICACY" -log "$@" >"$LOG" 2>&1
rc=$?
cat "$LOG"
tail -c 10000 "$LOG" | curl -fsS -m 10 --retry 3 -o /dev/null \
--data-binary @- "$URL/$rc" || true
exit $rc
Cron example (run from the repository directory):
0 2 * * * cd /srv/data && WATCHGOOSE_URL=https://watchgoose.com/ping/your-check-uuid /usr/local/bin/duplicacy-watchgoose.sh backup -stats
It works for check, prune and copy too, just give each one its own check.
What I saw in testing - a successful backup sent /start and /0 with the log, a wrong storage password sent /start and /100 with the STORAGE_CONFIG ... message authentication failed line, and a missing storage sent /100 with STORAGE_NOT_CONFIGURED.
Watchgoose has a support plan for Open Source maintainers (Open Source Program - Watchgoose). I am happy to answer any questions.
Cheers!