Scheduled Jobs

Automate recurring tasks with scheduled jobs. Run scripts inside containers or on the host with retry, overlap control, chaining, and failure notifications.

Scheduled Jobs

Scheduled jobs let you run recurring tasks on your server using cron. You can manage them from the web dashboard, CLI, or API.

Job Types

Container Jobs

Container jobs run inside a Docker container. The script is piped into the container via docker exec -i, giving it access to the container's filesystem, installed tools, and runtime environment.

Common use cases:

  • Database maintenance: node scripts/cleanup.js inside your app container
  • Cache operations: redis-cli FLUSHEXPIRED inside redis
  • CMS tasks: php artisan schedule:run inside a Laravel container
  • Report generation, data exports, queue workers

How it works: The script file lives on the host at /opt/onelift/scripts/jobs/<slug>.sh. At execution time, the runner pipes it into the container:

cat /opt/onelift/scripts/jobs/<slug>.sh | docker exec -i <container> bash

Host Jobs

Host jobs run directly on the server as root. They have access to Docker commands, the filesystem, and system utilities.

Common use cases:

  • Disk cleanup: pruning old Docker images, removing temp files
  • Backup management: rotating backup files, verifying integrity
  • System maintenance: log rotation, monitoring checks
  • Docker operations: docker system prune, container health checks

Managing Jobs

Web Dashboard

Navigate to Project > Scheduled Jobs to create and manage jobs.

Creating a job:

  1. Click "Add Job"
  2. Choose job type (Container or Host)
  3. For container jobs: select the tool/container
  4. Write your script in the built-in editor
  5. Set the schedule using the visual builder or cron expression
  6. Configure timeout, overlap policy, and retry settings
  7. Optionally enable failure notifications

Monitoring:

  • View execution history with exit codes and durations
  • Check latest log output
  • See success rate statistics
  • Run jobs manually for testing

CLI

See lift cron for full CLI documentation.

# Add a container job
lift cron add --name "DB Cleanup" --container strapi-app \
  --script-file ./cleanup.sh --schedule "0 3 * * *"

# Add a host job
lift cron add --name "Docker Prune" --type host \
  --command "docker system prune -f" --schedule "0 4 * * 0"

# View status and history
lift cron status
lift cron history "DB Cleanup"

# Edit script on the fly
lift cron edit "DB Cleanup"

Overlap Policies

Controls behavior when a job is triggered while the previous run is still active.

PolicyBehaviorBest For
skip (default)Don't start if already runningMost jobs — prevents pile-up
queueWait for current run to finish, then startData processing where every run matters
killStop current run, start new oneJobs where only the latest execution matters

Retry on Failure

Jobs can automatically retry when they fail (non-zero exit code).

SettingDescription
Max attemptsNumber of retries (0 = no retry)
DelaySeconds between retries
Backofffixed (same delay) or exponential (delay doubles each retry)

Example with exponential backoff (delay=10, max=3):

  • Attempt 1: immediate
  • Attempt 2: wait 10s
  • Attempt 3: wait 20s
  • Attempt 4: wait 40s

Job Chaining

Jobs can trigger other jobs upon completion. Configure a "Chain After Job" to run another job when the current one finishes.

Conditions:

  • On success — Chain runs only if the parent job succeeds (exit code 0)
  • On failure — Chain runs only if the parent job fails
  • Always — Chain runs regardless of the parent job's exit code

Depth limit: Chains are limited to 5 levels to prevent infinite loops. Circular chains are detected and blocked at creation time.

Failure Notifications

Enable "Notify on failure" to receive alerts when a job fails repeatedly.

  • Set a consecutive failure threshold (default: 3)
  • Choose notification channels: email, Slack, Telegram, Discord, webhook
  • Notifications are sent after the threshold is reached (not on every failure)

Environment Variables

Pass environment variables to your job scripts.

CLI:

lift cron add --name "Report" --container app \
  --command "node report.js" --schedule "0 8 * * 1" \
  --env REPORT_TYPE=weekly --env SEND_EMAIL=true

Dashboard: Use the Environment Variables section in the job form. Toggle the "Secret" flag to mask sensitive values in the UI.

For container jobs, env vars are passed via docker exec -e KEY=VALUE. For host jobs, they are exported before script execution.

Execution Logs

Each job run produces:

  • Run log: Full stdout/stderr output at /var/log/onelift/jobs/<slug>/run_<timestamp>.log
  • Latest log: Symlink to the most recent run at /var/log/onelift/jobs/<slug>/latest.log
  • History: JSONL file with metadata (exit code, duration, timestamp) at /var/log/onelift/jobs/<slug>/history.jsonl

View logs from the dashboard ("View Log" button) or CLI (lift cron log <name>).

Logs are automatically rotated daily with 14-day retention.

Timeout

Jobs have a configurable timeout (default: 300 seconds, max: 3600 seconds / 1 hour). If a job exceeds its timeout, it is killed with exit code 124.

Timed-out runs are marked as TIMEOUT in the history.