One-shot jobs
A one-shot job runs a command in a fresh container built from an app’s current image, with the app’s env, secrets, volumes and network, the same way a scheduled job does in its default mode. It can run the command several times, some of them side by side, retry failures, and report one final status.
A failed attempt is retried after an exponentially growing delay (first delay
APP_JOBS_RETRY_BACKOFF, capped by APP_JOBS_RETRY_BACKOFF_MAX). Every attempt is a normal run: it appears in jobs history <app> with its output and exit code. An attempt that has to wait because the app already has APP_JOBS_MAX_CONCURRENT_PER_APP jobs running is not a failure and spends none of the backoff budget.
The job ends Succeeded when all completions succeeded, or Failed once more than backoff-limit attempts have failed. The status carries the counts: completions succeeded, failed attempts, runs in flight and the IDs of the runs.
API
POST /api/v1/jobs/runs starts a job and answers 202 with its status. GET /api/v1/jobs/runs/{id} returns the status. Starting needs the same permission as running a scheduled job now (deploy on the app); reading needs read.
Settings
Limits today
- The job summary is held in memory by the control plane. After a restart
GETanswers 404, though the individual runs stay in the run history. A run in flight during a restart is marked interrupted and not resumed. - The command runs against an app. Running a bare image with no app is not supported yet.
- Each job leaves a hidden, disabled task row so its runs have a history to live in. It is named
oneshot-<job id>and shows injobs list.