media: run qbit_manage under Dagu as apps, alert when a pass stops landing #388

Merged
mysticalsoap merged 3 commits from feat/qbit-manage-dagu into trunk 2026-10-07 19:49:08 -04:00
Owner

Problem

qbit_manage scheduled itself inside its container with no completion signal anywhere, so when it started exiting at startup on qBittorrent 5.2.4 (#383) nothing noticed for six days. It also ran as root: the compose carried the privilege-drop cap set but never the PUID/PGID that make the image's init drop, and docker exec would bypass that init anyway. The just restart-invidious/just prune recipes and the "ad-hoc run" docs line were broken the same way the bare Dagu CLI is (no auth env in the exec).

Fix

  • Dagu runs it. The container idles (sleep infinity, user: apps, caps dropped); dagu/dags/qbit-manage.yaml execs media/qbit_manage/run.sh every six hours, which reads the API key from the secret and runs one --run pass. The schedule leaves the compose env.
  • Success mark + alerts. dagu/jobs/common/mark_success.sh (generic, in dagu-tools, which now mounts the textfile dir) writes qbit_manage_last_success_timestamp_seconds only after the pass succeeds. QbitManageStale (>13h, two missed passes) and QbitManageMetricMissing (absent 6h), same shape as the backup and image-scan groups.
  • just run-job <name> supplies the Dagu CLI's basic-auth env; restart-invidious and prune use it.
  • Docs: Maintenance (job row, paragraph, ad-hoc line), Monitoring (textfile row, rule group), Media setup §9 (one-time reown of the log/backup dirs, first-run and version-bump steps rewritten for Dagu), Adding-a-New-Service gets a "decide and check the run-as user" step.

Verification

Live, 2026-10-07:

  • docker top qbit_manage: tini and sleep infinity as apps. Log and backup dirs reowned by hand first (the step the setup page now has).
  • just run-job qbit-manage: Result: Succeeded; the pass log ends in Exiting Qbit_manage, the log file is now apps:apps; qbit_manage.prom written apps:apps with the timestamp.
  • Prometheus after just recreate prometheus: promtool check rules 36 rules OK; /api/v1/rules lists QbitManageStale and QbitManageMetricMissing; time() - qbit_manage_last_success_timestamp_seconds returns 26 s. QbitManageMetricMissing sat pending for the minutes between the recreate and the first pass, as designed, and clears with the metric present.
  • just --list shows run-job; dagu status inside the container works with the env the recipe sets.

Closes #385

🤖 Generated with Claude Code

## Problem qbit_manage scheduled itself inside its container with no completion signal anywhere, so when it started exiting at startup on qBittorrent 5.2.4 (#383) nothing noticed for six days. It also ran as root: the compose carried the privilege-drop cap set but never the `PUID`/`PGID` that make the image's init drop, and `docker exec` would bypass that init anyway. The `just restart-invidious`/`just prune` recipes and the "ad-hoc run" docs line were broken the same way the bare Dagu CLI is (no auth env in the exec). ## Fix - **Dagu runs it.** The container idles (`sleep infinity`, `user: apps`, caps dropped); `dagu/dags/qbit-manage.yaml` execs `media/qbit_manage/run.sh` every six hours, which reads the API key from the secret and runs one `--run` pass. The schedule leaves the compose env. - **Success mark + alerts.** `dagu/jobs/common/mark_success.sh` (generic, in dagu-tools, which now mounts the textfile dir) writes `qbit_manage_last_success_timestamp_seconds` only after the pass succeeds. `QbitManageStale` (>13h, two missed passes) and `QbitManageMetricMissing` (absent 6h), same shape as the backup and image-scan groups. - **`just run-job <name>`** supplies the Dagu CLI's basic-auth env; `restart-invidious` and `prune` use it. - Docs: Maintenance (job row, paragraph, ad-hoc line), Monitoring (textfile row, rule group), Media setup §9 (one-time reown of the log/backup dirs, first-run and version-bump steps rewritten for Dagu), Adding-a-New-Service gets a "decide and check the run-as user" step. ## Verification Live, 2026-10-07: - `docker top qbit_manage`: tini and `sleep infinity` as `apps`. Log and backup dirs reowned by hand first (the step the setup page now has). - `just run-job qbit-manage`: `Result: Succeeded`; the pass log ends in `Exiting Qbit_manage`, the log file is now `apps:apps`; `qbit_manage.prom` written `apps:apps` with the timestamp. - Prometheus after `just recreate prometheus`: `promtool check rules` 36 rules OK; `/api/v1/rules` lists `QbitManageStale` and `QbitManageMetricMissing`; `time() - qbit_manage_last_success_timestamp_seconds` returns 26 s. `QbitManageMetricMissing` sat pending for the minutes between the recreate and the first pass, as designed, and clears with the metric present. - `just --list` shows `run-job`; `dagu status` inside the container works with the env the recipe sets. Closes #385 🤖 Generated with [Claude Code](https://claude.com/claude-code)
`docker exec dagu dagu start` fails with "basic auth requires both
username and password": the entrypoint exports the password only to the
server process. A run-job recipe supplies both; restart-invidious and
prune go through it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
qbit_manage scheduled itself inside its container, so a pass that died
at startup was invisible: it exited on qBittorrent 5.2.4 for six days
before anyone looked (#383). The container now idles and a Dagu DAG
runs one --run pass every six hours, with a second step that writes
qbit_manage_last_success_timestamp_seconds to node-exporter's textfile
dir only after the pass succeeds. QbitManageStale fires at 13h (two
missed passes), QbitManageMetricMissing if the metric never appears,
the same shape as the backup and image-scan rules. mark_success.sh is
generic for any DAG that wants the same.

It also ran as root: the image's init drops to PUID/PGID, but the
compose never set them, and a docker exec would bypass that init
anyway. user: apps outright, caps dropped; its log and backup dirs need
reowning once, which the setup page now says.

Closes #385

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
docs: new-service checklist decides and checks the run-as user
All checks were successful
validate / validate (pull_request) Successful in 25s
ae560e2bc6
qbit_manage was added with the privilege-drop cap set but never the
PUID/PGID that make the init drop, and ran as root unnoticed until the
Dagu conversion looked. The checklist had no step for it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mysticalsoap deleted branch feat/qbit-manage-dagu 2026-10-07 19:49:08 -04:00
Sign in to join this conversation.
No description provided.