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.jsinside your app container - Cache operations:
redis-cli FLUSHEXPIREDinside redis - CMS tasks:
php artisan schedule:runinside 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:
- Click "Add Job"
- Choose job type (Container or Host)
- For container jobs: select the tool/container
- Write your script in the built-in editor
- Set the schedule using the visual builder or cron expression
- Configure timeout, overlap policy, and retry settings
- 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.
| Policy | Behavior | Best For |
|---|---|---|
| skip (default) | Don't start if already running | Most jobs — prevents pile-up |
| queue | Wait for current run to finish, then start | Data processing where every run matters |
| kill | Stop current run, start new one | Jobs where only the latest execution matters |
Retry on Failure
Jobs can automatically retry when they fail (non-zero exit code).
| Setting | Description |
|---|---|
| Max attempts | Number of retries (0 = no retry) |
| Delay | Seconds between retries |
| Backoff | fixed (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.