Wiederkehrende Aufgaben mit Taskwarrior
Ich hatte bereits erwähnt, dass ich Taskwarrior für wiederkehrende Aufgaben auf einem Server installiert hatte. Nun möchte ich noch einmal genauer darauf eingehen, weil sich das Ganze als nicht trivial herausstellte.
Übersetzung nach Anleitung
Doch der Reihe nach. Das Übersetzen an sich war schmerzlos, verdient aber trotzdem einige Anmerkungen.
Das System läuft mit Debian 13 (Trixie).
Taskwarrior wird mit rustc und cargo kompiliert,
die es zwar beide in den Debian Repositories gibt,
allerdings in zu alten Versionen.
Nun könnte ich zwar nach einem DEB-Paket für eine passende Version suchen,
der einfachere Weg ist jedoch,
rustc und cargo nicht aus den Debian-Repositories zu nehmen,
sondern stattdessen rustup den Rust Toolchain Installer.
sudo apt install rustup
rustup default stable
Damit bekam ich eine hinreichend neue Version für das Übersetzen von Taskwarrior.
Außerdem brauchte ich noch einige Pakete aus der Entwickler-Toolchain.
sudo apt install cmake make g++ uuid-dev
Damit konnte es losgehen. Als erstes besorgte ich die Quellen von GitHub und checkte die stabile Version aus.
git clone https://github.com/GothenburgBitFactory/taskwarrior.git taskwarrior.git
cd taskwarrior.git
git checkout stable
Damit konnte ich Taskwarrior bauen. Tatsächlich habe ich den nächsten Schritt zweimal gemacht, weil das Übersetzen mit 512 MB RAM wegen Speichermangel abbrach. Mit 1 GB RAM lief die Übersetzung durch.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
Am Ende kontrollierte ich kurz, ob die Kompilierung durchgelaufen war und ich die richtige Version hatte, dann habe ich Taskwarrior im System installiert.
build/src/task --version
sudo cmake --install build
Skript für Anlegen wiederkehrender Aufgaben und Synchronisation
Als nächstes galt es Taskwarrior regelmäßig aufzurufen, um wiederkehrende Aufgaben anzulegen und dann mit dem Syncserver abzugleichen.
Als erstes konfigurierte ich Taskwarrior für die Synchronisation in ~/.taskrc:
recurrence=on
sync.server.client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
sync.encryption_secret=XYZxyz
sync.server.url=https:\/\/sync.server
Der Eintrag recurrence=on weist Taskwarrior an,
wiederkehrende Aufgaben neu anzulegen.
Diese Angabe darf nur bei einem
der an der Synchronisation beteiligten Clients
eingestellt sein.
Die sync.* Einstellungen habe ich von einem der anderen Clients kopiert.
Damit konnte ich die Synchronisation testen
/usr/local/bin/task sync
/usr/local/bin/task
Der zweite Aufruf zeigte die aktiven Aufgaben wie bei den anderen Clients an.
Beide Aufrufe habe ich in einem Skript in ~/bin/tasksync.bash zusammengefasst.
#!/bin/bash
/usr/local/bin/task rc:/home/tasks/.taskrc rc.verbose=nothing --quiet || true
/usr/local/bin/task rc:/home/tasks/.taskrc rc.verbose=nothing sync || true
Dieses Skript wird von einem Systemd-User-Service aufgerufen, welcher seinerseits durch einen Systemd-Timer aktiviert wird.
Zeitgesteuerter Aufruf mit Systemd
Damit ich Systemd-User-Services und Timer nutzen kann,
ohne angemeldet zu sein,
muss root das mit loginctl freischalten.
sudo loginctl enable-linger tasks
Der User-Service selbst ist in ~/.config/systemd/user/tasksync.service definiert und sah zunächst in etwa so aus:
[Unit]
Description=Create Recurring tasks and sync
[Service]
ExecStart=/home/tasks/bin/tasksync.bash
RemainAfterExit=no
Type=oneshot
[Install]
WantedBy=default.target
Der Timer wiederum ist in ~/.config/systemd/user/tasksync.timer definiert und sieht so aus:
[Unit]
Description=Tasksync
[Timer]
OnBootSec=15min
OnUnitActiveSec=5min
Persistent=true
[Install]
WantedBy=default.target
Anschließend machte ich Systemd den Service und den Timer bekannt, startete den Service und kontrollierte den Status.
systemctl --user daemon-reload
systemctl --user start tasksync.service
systemctl --user status tasksync.service
Die Ausgabe des letzten Befehls sah etwa so aus:
* tasksync.service - Create Recurring tasks and sync
Loaded: loaded (/home/tasks/.config/systemd/user/tasksync.service; enabled; preset: enabled)
Active: inactive (dead) since Tue 2026-08-25 17:34:35 CEST; 59min ago
Invocation: d98b566f95a34b749ae37ed0cc3b2895
TriggeredBy: * tasksync.timer
Process: 7331 ExecStart=/home/tasks/bin/tasksync.bash (code=exited, status=0/SUCCESS)
Main PID: 7331 (code=exited, status=0/SUCCESS)
Mem peak: 3.2M
CPU: 189ms
Aug 10 17:34:35 srv06 systemd[646]: Starting tasksync.service - Create Recurring tasks and sync...
Aug 10 17:34:35 srv06 systemd[646]: Finished tasksync.service - Create Recurring tasks and sync.
Da es soweit funktionierte, aktivierte ich den Timer und kontrollierte noch einige Zeit lang den Status.
systemctl --user enable --now tasksync.timer
systemctl --user list-timers
Problem nach Neustart
Soweit so gut, ich bekam regelmäßig wiederkehrende Tasks, bis ich nach einiger Zeit bemerkte, dass diese ausblieben.
Als ich auf dem Server nachsah, fand ich folgendes in der Statusausgabe:
$ systemctl --user status tasksync.service --no-pager -l
* tasksync.service - Create Recurring tasks and sync
Loaded: loaded (/home/tasks/.config/systemd/user/tasksync.service; enabled; preset: enabled)
Active: inactive (dead) since Thu 2026-08-20 20:03:34 CEST; 47s ago
Invocation: 6e9c56e27ca24b95a6fd04d9be2b7ac6
TriggeredBy: * tasksync.timer
Process: 664 ExecStart=/home/tasks/bin/tasksync.bash (code=exited, status=0/SUCCESS)
Main PID: 664 (code=exited, status=0/SUCCESS)
Mem peak: 19.1M
CPU: 180ms
Aug 20 20:03:34 srv06 systemd[645]: Starting tasksync.service - Create Recurring tasks and sync...
Aug 20 20:03:34 srv06 tasksync.bash[667]: Failed to synchronize with server: Server Error: https://encrypted.mamawe.net:8443/v1/client/get-child-version/7c205863-a581-4778-8ddf-6fa5d0f5a3a5: Dns Failed: resolve dns name 'encrypted.mamawe.net:8443': failed to lookup address information: Temporary failure in name resolution
Aug 20 20:03:34 srv06 systemd[645]: Finished tasksync.service - Create Recurring tasks and sync.
Als ich mir die anderen Logs des Servers anschaute, bemerkte ich, dass dieser kurz davor neu gestartet war. Das Problem war also, dass der Timer beim Systemstart bereits feuerte, bevor das Netzwerk und damit DNS verfügbar war.
Ich befragte dazu den Chatbot meines Vertrauens, der mir erklärte, dass eine Systemd-User-Unit nicht von einer System-Unit abhängen kann. Dementsprechend konnte ich den TaskSync-Service nicht direkt von networking.service abhängig machen.
Als einfachste Lösung schlug der Chatbot einen PreCheck im TaskSync-Service vor, den ich dort einfügte.
[Service]
ExecStartPre=/bin/sh -c 'i=0; until getent hosts encrypted.mamawe.net >/dev/null 2>&1; do i=$((i+1)); [ $i -gt 30 ] && echo "DNS-Timeout" && exit 1; sleep 5; done'
...
Zum Test trennte ich die VM vom Netz und startete den Service.
systemctl --user status tasksync.service
Der TaskSync-Service brauchte nun länger als normal,
bis er nach zweieinhalb Minuten in den Timeout lief.
systemctl status zeigte folgendes an:
× tasksync.service - Create Recurring tasks and sync
Loaded: loaded (/home/tasks/.config/systemd/user/tasksync.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Sat 2026-08-22 18:21:24 CEST; 1min 13s ago
Invocation: 8be5c3ffdce04cc4b7be42a6c6a5f154
TriggeredBy: * tasksync.timer
Process: 3290 ExecStartPre=/bin/sh -c i=0; until getent hosts encrypted.mamawe.net >/dev/null 2>&1; do i=$((i+1)); [ $i -gt 30 ] && echo "DNS-Time>
Mem peak: 1.8M
CPU: 38ms
Aug 22 18:18:54 srv06 systemd[646]: Starting tasksync.service - Create Recurring tasks and sync...
Aug 22 18:21:24 srv06 sh[3290]: DNS-Timeout
Aug 22 18:21:24 srv06 systemd[646]: tasksync.service: Control process exited, code=exited, status=1/FAILURE
Aug 22 18:21:24 srv06 systemd[646]: tasksync.service: Failed with result 'exit-code'.
Aug 22 18:21:24 srv06 systemd[646]: Failed to start tasksync.service - Create Recurring tasks and sync.
Die Meldung zum DNS-Timeout ist eindeutig und die zweieinhalb Minuten sollten ausreichen, um das Netzwerk beim Neustart des Systems zu aktivieren.
Nachdem ich das Netzwerk wieder zugeschaltet hatte und den Service erneut startete, lief dieser bis jetzt fehlerfrei durch.