Jobs and CronJobs
Run one-off Jobs and scheduled CronJobs on nyxory — batch work, migrations, nightly data jobs — deployed by your agent the same way it deploys an app.
Some work isn’t a server. A migration before a cutover or a nightly database dump starts, does its job, exits 0, and is done. A Job runs once; a CronJob runs on a schedule. Your agent deploys either one the same way it deploys an app.
Deploying one
Two steps, the same as any app minus the server parts:
- Build the image.
nyx_build_and_push_imagefrom your repo — the same build path. - Deploy the manifest.
nyx_deploy_manifestswith the Job or CronJob spec. Like every object the app owns, it carries the App ownerReference and the app’sapp.kubernetes.io/instancelabel.
A Job or CronJob gets no Service, no domain, and no probes — there’s nothing to route traffic to and nothing to health-check. The only signal that matters is whether the run completed.
Scheduling recurring work
A CronJob runs a container on a schedule you set, which makes it the workhorse behind day-to-day operations an agent sets up once and then leaves running:
- A nightly database backup to your object store (on the shared platform, backups are otherwise on demand, see Storage and backups).
- An hourly data-consolidation or sync job: pull, transform, write, exit.
- A periodic cache warm or cleanup pass.
Your agent writes the schedule (spec.schedule in standard cron syntax) and applies it; from there the container fires on its own. The work in the container is yours to define — the CronJob just guarantees it runs on time.
With auto-deploy on, a push reaches CronJobs too: nyxory rolls the new image into the CronJob’s template, and the next scheduled run uses it. A one-off Job is not updated this way; its pod template can’t change, so rerun it yourself.
Verifying a run
Don’t wait for a 1/1 Ready pod and don’t curl anything — neither ever comes. Check completion status, then read that pod’s logs for the actual result.
Note: A Job is healthy when
status.succeeded: 1. A CronJob is healthy whenlastSuccessfulTimeis afterlastScheduleTime. A still-running pod means “in progress,” not broken; a pod that’s disappeared means “already finished,” not failed — completion status is what tells them apart.
Making it safe to re-run
The platform doesn’t make re-runs idempotent — the job’s own logic has to, because a redeploy or a missed tick can run the work twice. Guard it: append-only writes, skip-if-done checks, INSERT ... ON CONFLICT DO NOTHING, or a migration tool that tracks which versions already ran.
Two spec settings keep a schedule from causing damage under load — a firing CronJob draws on the same namespace RAM/CPU quota as any running Deployment, so set real requests/limits on it too:
concurrencyPolicy: Forbid(orReplace) stops overlapping ticks from stacking up if one run outlasts its interval.backoffLimitcaps retries so a broken job can’t spawn pods indefinitely.
Relevant tools: nyx_build_and_push_image, nyx_deploy_manifests, nyx_shell (for kubectl delete job/<name> and status/log reads).