Jobs

Commands on a schedule, each run kept with its output.

Overview

A job runs a command on a schedule — every night, every hour, on Mondays — in a short-lived container. Every run is kept with its exit code, duration and the last lines it printed.

A job can run with its own image, or with one of your apps’ image, environment and secrets.

When to use it

  • Clean up old files or rows every night.
  • Send a report every Monday.
  • Sync data from another service every hour.

How it works

Scheduler
A loop in the reconciler that ticks every second and claims due runs in one SQLite transaction, so a run is never started twice.
Cron schedules
Five-field cron and @hourly, @daily, @weekly, @monthly, evaluated in an IANA time zone (the machine’s unless you choose).
Docker Engine
Each run is its own container, removed when it ends.

When a run is due, the scheduler records it and starts its container with the command, the environment and the secrets. It waits up to the timeout, then records the exit code and the end of the output.

If the previous run is still going, the next one is skipped unless you allow overlaps.

Architecture

Jobs architectureThe scheduler starts a container per run and keeps the outcome.startby nameresultSchedulerticks every secondRun containerimage or app’s imageYour databaseor any resource itcallsRun historyexit code, output tail
The scheduler starts a container per run and keeps the outcome.
  • Scheduler to Run container: start
  • Run container to Your database: by name
  • Run container to Run history: result

Flows

A scheduled run

  1. The schedule comes due (or you press Run now).
  2. The scheduler claims the run and starts its container.
  3. The command does its work, reaching other resources by name.
  4. The run ends, or is stopped at its timeout; its exit code and last lines are kept.

Set it up

In the console

  1. Open Jobs and choose New job.
  2. Give it a name, a schedule and the command.
  3. Choose an image, or an app to borrow its image and settings.
  4. Use Run now to try it.

With the CLI

enclave job create nightly-report --image alpine:3 --schedule "0 2 * * *" --wait -- echo hello

With OpenTofu

OpenTofu configuration
resource "enclave_job" "nightly_report" {
  name     = "nightly-report"
  image    = "alpine:3"
  schedule = "0 2 * * *"
  command  = ["echo", "hello"]
}

Settings reference

Every setting and output of the OpenTofu resource; the console and the CLI use the same names in their own words. Generated from platform 4d30582.

enclave_job
NameTypeUseWhat it does
nametextrequiredName of the job: 3–40 lowercase letters, digits or hyphens, starting with a letter. Changing it replaces the job.
scheduletextrequired5-field cron ("0 3 * * *") or @hourly, @daily, @weekly, @monthly.
apptextoptionalRun with this app's image and environment. Exactly one of app or image.
commandlist of textoptionalCommand and arguments (default: the image's or app's).
envmap of textoptionalEnvironment variables; they override an app's.
imagetextoptionalRun this image. Exactly one of app or image.
machinetextoptionalThe machine to run on (default: EnclaveStack chooses, and this reads back its choice). Changing it moves the resource, with its data, in place; apply waits for the move.
machine_labelsmap of textoptionalLabels the machine must have, when machine isn't set (key=value, all must match).
memory_mibnumberoptionalMemory limit in MiB (64–16384).
networktextoptionalNetwork to place it in (default: the default network). Changes in place.
overlaptextoptionalforbid: skip a run while one is going; allow: run anyway.
projecttextoptionalThe project to create it in. Defaults to the provider's project (ENCLAVE_PROJECT, else default). Changing it replaces the resource.
secret_envmap of textoptionalEnvironment variables from secrets: variable name → secret name.
subnettextoptionalSubnet of the network (default: its first).
time_zonetextoptionalIANA time zone for the schedule (default: the machine's).
timeout_secondsnumberoptionalStop a run after this many seconds (1–86400).
volumeslist of objectsoptionalFilesystem volumes mounted into every container; a change deploys a new revision.
idtextoutputResource ID.
last_run_statustextoutputsucceeded, failed, timed_out or skipped.
next_run_attextoutputWhen the next run is due (RFC 3339).

Limits and security

Good to know

  • @every intervals are not accepted; use cron fields.
  • A run that passes its timeout is stopped.

Security

  • Runs get the same secrets handling as apps: decrypted into the environment at start, never logged.