Cron (scheduled commands)
The Cron tab runs a command on the server on a schedule: a Laravel scheduler, a nightly cleanup, a report emailed every Monday. You set it up from the panel, and you never have to SSH in to edit a crontab.
It uses the server's own cron. The panel keeps the list and the agent writes it to the machine. So the job keeps running on time even when the panel is unreachable, and a nightly job does not skip a night because CloudPilot had an outage.
Scheduled tasks are CloudPilot's own jobs, like backups and agent updates. Cron runs your commands on your server.
Adding a command#
- Open the server → Cron → New command.
- Give it a name, just for your own reference.
- Choose when it runs. Pick a common schedule from the list or type one; the form reads it back in words ("Every weekday at 22:15") so you can catch a typo before you save.
- Enter the command. It runs with
/bin/sh, so pipes,&&and redirects work the same as in a terminal. - Choose the user it runs as. This is usually your app's own user, such as
www-data. - Optionally, set a working directory, such as
/var/www/app, and a time limit. - Schedule it.
The change is applied on the server first and saved in the panel only after the server accepts it. If the server refuses, for example because the user doesn't exist there, nothing is saved and the form tells you why.
Common examples#
| What | Schedule | Command |
|---|---|---|
| Laravel scheduler | * * * * * |
php artisan schedule:run (working directory: your app) |
| Django: clear expired sessions | 0 3 * * * |
python manage.py clearsessions |
| Delete temp files older than a week | 0 4 * * 0 |
find /var/www/app/tmp -type f -mtime +7 -delete |
| Ping a health check | */5 * * * * |
curl -fsS https://hc-ping.com/your-uuid > /dev/null |
Schedules#
A schedule has five parts: minute, hour, day of month, month, day of week.
| Schedule | Means |
|---|---|
* * * * * |
Every minute |
*/15 * * * * |
Every 15 minutes |
0 * * * * |
Every hour, on the hour |
0 3 * * * |
Every day at 03:00 |
30 22 * * 1-5 |
Weekdays at 22:30 |
0 3 * * 0 |
Sundays at 03:00 |
0 3 1 * * |
The 1st of every month at 03:00 |
@hourly, @daily, @weekly and @monthly also work.
Times are in the server's time zone, which is often UTC and may not match yours.
@reboot is refused on purpose. It runs once when the server starts and then
never again, so it is not really a schedule. To start something when the
server boots, use a service; see Services and processes.
Which user to run as#
Use the user your app runs as. A command run as that user can do exactly what your app can do, and no more.
Running as root has to be confirmed with a checkbox. A command run as
root can change anything on the server, so reserve it for jobs that really
need it, such as renewing certificates.
What happens on each run#
- One run at a time. If a command is still running when its next run is due, the new run is skipped and recorded as skipped. It is not queued behind the old one. Without this, a slow job that runs every minute piles up copies of itself until the server falls over.
- A time limit. A run still going after its limit (one hour by default, 24 hours at most) is stopped, along with anything it started. That way a hung command can't block every run after it.
- Output is kept. The last 16 KB of each run's output is recorded, together with its exit code and how long it took. The end of the output is kept, because that is where errors usually are.
Run history#
Each command in the list shows its latest result: Succeeded, Failed (exit N), Stopped (it hit the time limit) or Skipped.
Click History to see recent runs and open any of them to read its output. The history lives on the server, not in the panel. The server keeps up to the last 500 runs, or 2 MB, per command.
Testing a command#
Run now runs a command immediately, as its own user and through the same path the schedule uses. So if it works here, it will work at 3am. If the run finishes within 30 seconds, its output opens straight away. A longer run keeps going in the background, and its result appears in the history when it's done.
Pausing and deleting#
Pause stops a command from running but keeps its settings and history. Resume turns it back on.
Delete removes the command from the server along with its run history. Commands often contain tokens, so nothing is left behind on disk.
If the list and the server disagree#
If the server's copy stops matching the panel, the tab shows a warning with a Re-apply button. This can happen if the agent was reinstalled or someone edited the files by hand. Re-apply writes the panel's list to the server again.
Edits made directly to /etc/cron.d/cloudpilot are overwritten. Your own
crontabs, such as crontab -e and other files in /etc/cron.d, are never
touched.
Who can use it#
| Permission | Allows |
|---|---|
cron.view |
See commands, their schedules and their run output |
cron.manage |
Create, edit, pause, delete and run commands |
Owners, Admins and DevOps have both by default. Developers and Viewers have neither, because commands and their output often contain secrets. You can grant either permission to a custom role; see Roles and permissions.
Every change and every manual run is recorded in the audit log. The log records the command's name, schedule and user, but never the command itself.
Requirements#
- The server must be online to add, change or run commands. The list stays visible while it's offline.
- The server needs an up-to-date agent. If the agent is too old, the tab tells you to update it; see Updating the agent.
Raise a ticket and someone will pick it up. Sign in with the same account you use for the panel.
Raise a ticket