Skip to content

Triggering a task remotely

Sometimes the task lives on one machine and the thing that wants to run it lives on another — a deploy script on your laptop, a cron job on a jump host, a CI runner. You don’t want to SSH in, remember the exact command, and lose the output to a scrollback buffer. You want to poke the daemon, watch what happens, and have your script stop if it fails.

That’s one command:

Terminal window
runwisp exec backup --url https://runwisp.example.com

It logs in, triggers the backup task, streams its stdout/stderr to your terminal live, and exits with the task’s exit code — so runwisp exec backup --url … && deploy.sh does the right thing. Every trigger still lands as a browsable run in the daemon’s history, with timestamps, exit code, and captured output, exactly like a scheduled run.

Install the runwisp binary wherever your script runs (it’s a single static binary — no daemon, no data dir needed for this), then point exec at the remote daemon:

Terminal window
export RUNWISP_URL=https://runwisp.example.com
export RUNWISP_PASSWORD=# the daemon's password
runwisp exec backup # --url falls back to RUNWISP_URL

RunWisp does the CHAP handshake for you, caches the resulting session token under your user cache dir ($XDG_CACHE_HOME/runwisp/ on Linux, ~/Library/Caches/runwisp/ on macOS), and reuses it on the next call. That matters: the daemon rate-limits logins, so a script that triggers a task every minute would get throttled if it re-authenticated each time. With the cached token, only the first call logs in; the rest just trigger.

The password can come from --password instead of the environment, but RUNWISP_PASSWORD keeps it out of your shell history and process list.

Fire-and-forget. If you only want to kick the task off and not wait around, add --detach — it prints the run ID and exits 0 immediately:

Terminal window
runwisp exec backup --detach
# 01ARZ3NDEKTSV4RRFFQ69G5FAV

You can quote that ULID back when you go looking for the run in the Web UI or runwisp history.

Two things, and they’re both about the daemon you’re triggering — not the machine you’re triggering from:

  1. It has to be reachable over the network. By default the daemon binds to loopback only. Bind it wider with runwisp daemon --host 0.0.0.0 and — please — put it behind a TLS-terminating reverse proxy rather than exposing plain HTTP. CHAP keeps your password safe, but not everything else: the session token and all the output ride over plain HTTP in the clear, and anyone who can watch the traffic can grab that token and reuse it. TLS is what closes that gap.
  2. The task allows API triggering. Tasks are triggerable over the API by default (api_trigger = true). If you’ve set api_trigger = false on a task to wall it off, the trigger comes back 403 and so does runwisp exec --url. Drop the line to re-enable it.

That’s the whole setup. The TOML on the daemon stays the single source of truth for what runs; the remote trigger only ever says when.