Cbox Init
Scheduled Tasks
Scheduled Tasks Example
Run periodic tasks like backups, reports, and maintenance jobs using Cbox Init's built-in cron scheduler.
Use Cases
- ✅ Replace cron in Docker containers
- ✅ Database backups and maintenance
- ✅ Report generation and data sync
- ✅ Cache warming and optimization
- ✅ Cleanup and housekeeping tasks
Cron Schedule Format
Cbox Init uses standard 5-field cron expressions:
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, 0=Sunday)
│ │ │ │ │
* * * * *
Special Characters:
*- Any value,- Value list separator (e.g.,1,3,5)-- Range (e.g.,1-5)/- Step (e.g.,*/15)
Common Schedule Patterns
schedule: "* * * * *" # Every minute
schedule: "*/15 * * * *" # Every 15 minutes
schedule: "30 * * * *" # Every hour at :30
schedule: "0 2 * * *" # Daily at 2 AM
schedule: "0 8 * * 1" # Every Monday at 8 AM
schedule: "0 0 1 * *" # First day of month at midnight
schedule: "0 9-17 * * 1-5" # Business hours (9 AM - 5 PM, Mon-Fri)
schedule: "0 3 * * 6,0" # Weekend only (Sat-Sun at 3 AM)
Complete Configuration
version: "1.0"
global:
log_format: json
log_level: info
api_enabled: true
api_port: 9180
processes:
# Database backup - Daily at 2 AM
database-backup:
enabled: true
command: ["php", "artisan", "backup:database"]
schedule: "0 2 * * *"
schedule_timeout: "10m"
restart: never
env:
BACKUP_PATH: /backups
RETENTION_DAYS: "30"
# Cache warming - Every 15 minutes
cache-warmer:
enabled: true
command: ["php", "artisan", "cache:warm"]
schedule: "*/15 * * * *"
schedule_max_concurrent: 1
restart: never
# Reports - Hourly during business hours
hourly-reports:
enabled: true
command: ["php", "artisan", "reports:generate"]
schedule: "0 9-17 * * 1-5" # 9 AM - 5 PM, Mon-Fri
restart: never
env:
REPORT_TYPE: hourly
OUTPUT_DIR: /var/www/storage/reports
# Log rotation - Daily at midnight
log-rotation:
enabled: true
command: ["/usr/local/bin/rotate-logs.sh"]
schedule: "0 0 * * *"
restart: never
env:
LOG_DIR: /var/log/app
COMPRESS: "true"
MAX_AGE_DAYS: "7"
# Data sync - Every 30 minutes
data-sync:
enabled: true
command: ["php", "artisan", "data:sync"]
schedule: "*/30 * * * *"
restart: never
env:
SYNC_SOURCE: remote-api
SYNC_BATCH_SIZE: "100"
# Weekly maintenance - Sunday at 3 AM
weekly-maintenance:
enabled: true
command: ["/usr/local/bin/weekly-maintenance.sh"]
schedule: "0 3 * * 0" # Sunday
restart: never
env:
OPTIMIZE_DATABASE: "true"
CLEAR_OLD_SESSIONS: "true"
Task Breakdown
1. Database Backup
database-backup:
command: ["php", "artisan", "backup:database"]
schedule: "0 2 * * *" # Daily at 2 AM
schedule_timeout: "10m"
restart: never
Laravel Command:
// app/Console/Commands/BackupDatabase.php
class BackupDatabase extends Command
{
protected $signature = 'backup:database';
public function handle()
{
$filename = 'backup-' . date('Y-m-d') . '.sql';
$path = env('BACKUP_PATH', '/backups');
// ... backup logic
$this->info("Backup created: {$path}/{$filename}");
return 0; // Success
}
}
2. Cache Warming
cache-warmer:
command: ["php", "artisan", "cache:warm"]
schedule: "*/15 * * * *" # Every 15 minutes
schedule_max_concurrent: 1
Runs every 15 minutes (00, 15, 30, 45). schedule_max_concurrent: 1 skips a
trigger if the previous run is still active.
3. Hourly Reports
hourly-reports:
schedule: "0 9-17 * * 1-5" # 9 AM - 5 PM, Mon-Fri
0- At minute 0 (top of hour)9-17- Hours 9 through 17 (9 AM - 5 PM)1-5- Monday through Friday
Inspecting Scheduled Tasks
Cbox Init records real per-task execution history and statistics. Enable the API
(api_enabled: true) and query it.
Status
curl http://localhost:9180/api/v1/processes/database-backup/schedule
{
"process": "database-backup",
"schedule": {
"name": "database-backup",
"schedule": "0 2 * * *",
"timezone": "UTC",
"state": "idle",
"last_run": "2026-08-26T02:00:00Z",
"next_run": "2026-08-27T02:00:00Z",
"stats": {
"total_executions": 42,
"success_count": 41,
"failure_count": 1,
"running_count": 0,
"success_rate": 97.62,
"average_duration": 45200000000,
"last_execution_time": "2026-08-26T02:00:00Z",
"last_success_time": "2026-08-26T02:00:45Z",
"last_failure_time": "2026-08-20T02:00:12Z"
}
}
}
average_duration is a Go duration in nanoseconds.
History
curl "http://localhost:9180/api/v1/processes/database-backup/schedule/history?limit=5"
Pause / Resume / Trigger
curl -X POST http://localhost:9180/api/v1/processes/database-backup/schedule/pause
curl -X POST http://localhost:9180/api/v1/processes/database-backup/schedule/resume
curl -X POST "http://localhost:9180/api/v1/processes/database-backup/schedule/trigger?sync=true"
Environment Variables
Scheduled task processes receive these environment variables in addition to
their own env:
CBOX_INIT_PROCESS=database-backup # The process name
CBOX_INIT_SCHEDULED=true # Marks this as a scheduled run
Use in scripts:
#!/bin/bash
echo "Running scheduled task: $CBOX_INIT_PROCESS"
Best Practices
✅ Do
Idempotent Tasks:
php artisan cache:clear # Safe to run repeatedly
php artisan backup:create # Creates a new backup each time
Error Handling:
#!/bin/bash
set -e # Exit on error
if [ -z "$BACKUP_PATH" ]; then
echo "ERROR: BACKUP_PATH not set"
exit 1
fi
php artisan backup:run
echo "Backup completed successfully"
Timeout Safety:
database-backup:
schedule: "0 2 * * *"
schedule_timeout: "10m" # Cancel if it exceeds 10 minutes
❌ Don't
Don't use long-running daemons:
# ❌ Bad - daemon processes don't work with schedule
schedule: "* * * * *"
command: ["./background-daemon"] # Never exits
# ✅ Good - one-time execution
command: ["./process-batch-then-exit"]
Don't forget restart: never:
# ❌ Bad - reruns immediately after finishing
scheduled-task:
schedule: "0 2 * * *"
restart: always
# ✅ Good - runs once per schedule
scheduled-task:
schedule: "0 2 * * *"
restart: never
Real-World Examples
PHP Framework Scheduled Tasks
processes:
# Laravel: use Laravel's built-in scheduler
laravel-scheduler:
command: ["php", "artisan", "schedule:run"]
schedule: "* * * * *"
restart: never
# Symfony: use the messenger scheduler transport
symfony-scheduler:
command: ["php", "bin/console", "messenger:consume", "scheduler_default", "--time-limit=50"]
schedule: "* * * * *"
restart: never
# WordPress: run WP-Cron via CLI
wordpress-cron:
command: ["php", "/var/www/html/wp-cron.php"]
schedule: "*/5 * * * *"
restart: never
Database Maintenance
db-optimize:
command: ["php", "artisan", "db:optimize"]
schedule: "0 4 * * 0" # Sunday 4 AM
restart: never
env:
DB_OPTIMIZE_TABLES: "users,orders,products"
Stagger Multiple Tasks
# Don't run everything at the same time
backup-database:
schedule: "0 2 * * *" # 2:00 AM
backup-files:
schedule: "15 2 * * *" # 2:15 AM
backup-logs:
schedule: "30 2 * * *" # 2:30 AM
See Also
- Scheduled Tasks (feature) - Full scheduler reference
- Process Configuration - Process settings
- Management API - Runtime task inspection