View .md

Cron and workers

How FeatherPanel runs scheduled jobs and background work, the cron runner, the async runner and which jobs run every minute, for Docker and source installs.

On this page

FeatherPanel has two kinds of background work: a cron runner that executes PHP and bash jobs every minute, and the async runner, a Rust service for longer jobs.

Docker installs

Nothing to set up. Inside the backend container supervisord runs two programs: frankenphp (the web server) and cron-runner. cron-runner.sh loops forever and, once a minute, runs:

  • php storage/cron/runner.php as www-data, under flock so only one run happens at a time, and killed after CRON_TIMEOUT seconds (default 900).
  • bash storage/cron/runner.bash.

Output goes to /var/log/cron.log inside the container:

docker exec featherpanel_backend tail -f /var/log/cron.log

The async runner is its own container, featherpanel_async_runner. It shares the logs volume with the backend.

Source installs

The source installer writes /etc/cron.d/featherpanel:

* * * * * www-data bash /var/www/featherpanel/backend/storage/cron/runner.bash >/dev/null 2>&1
* * * * * www-data php /var/www/featherpanel/backend/storage/cron/runner.php >/dev/null 2>&1

It builds the async runner with Cargo into runner/target/release/async-runner and installs it as the featherpanel-async-runner systemd service.

Jobs the runner executes

The PHP runner loads every file in backend/storage/cron/php/ (the glob order is alphabetical, which is why some jobs have an A, B or Z prefix), then the Cron/ folder of each installed plugin. Each job decides on its own whether it is due.

JobPurpose
AAdminBackupPolicyProcessorRuns due admin backup policies
ANodeBackupAgentProcessorRuns due Wings node backup policies
AServerAutoStartProcessorStarts servers queued for a staggered start after a node reconnects
AServerScheduleProcessorRuns due server schedules
BPlayerStatusPollerPolls player counts
BServerResourceSamplerStores a CPU, memory and disk sample per running server every five minutes and keeps one day
ProcessDueAccountDeletionsDeletes accounts whose scheduled deletion is due
UmamiTelemetryReporterSends usage telemetry when it is enabled
UserDataExportProcessorBuilds queued user data exports
ZAllocationCleanupOnce a day, unassigns allocations that point to servers that no longer exist
ZCheckExpiredServersEvery five minutes, suspends game servers and VMs past their expiry date
ZDeleteOldDataDeletes used or expired SSO tokens and soft-deleted mail templates, and prunes notifications (read ones after 30 days, all after 90)
ZFeatherZeroTrustScannerRuns the FeatherZeroTrust scanner
ZProxmoxConsoleUserCleanupRemoves temporary Proxmox console users

Plugins can add their own jobs. See Plugins.

Checking that cron runs

If schedules do not fire, backups do not start or the dashboard sparklines stay empty, the cron runner is the first thing to check:

docker exec featherpanel_backend ps aux | grep cron-runner
docker exec featherpanel_backend tail -n 50 /var/log/cron.log

Frequently asked questions

Do I need to add a crontab entry for FeatherPanel?

Not with Docker. The backend container runs a cron loop under supervisord. Source installs get /etc/cron.d/featherpanel from the installer.