How to set up native cron on WordPress in Digital Ocean
Recently, I faced a really bad situation (which could have been much worse) – my WordPress backups stopped without any notice.
I have been using an UpdraftPlus Backups plugin, and it was all fine until it stopped. Since I did not know the reason (and there were no evident signs of any abnormalities, broken plugins or scripts), I decided to switch to running native cron jobs.
My only guess now is that UpdraftPlus stopped working due to me making several performance and security adjustments on Cloudflare account.
As you might know, WordPress requires visitors to the website to run cron tasks, but this can be blocked by Cloudflare’s Bot Fight Mode.
So, to avoid being blocked, you can set up a cron job on your server instead of making an HTTP request.
This is how I did that:
Disable WP cron and Alternate cron
/* Add any custom values between this line and the "stop editing" line. */ define('ALTERNATE_WP_CRON', false); define('DISABLE_WP_CRON', true);
Set up cron jobs on your server
I run a Digital Ocean server, coupled with Forge. Initially, I was getting an error when trying to edit cron:
crontab –e –e: No such file or directory
So I ran the following command and was able to edit my cron jobs:
sudo apt install cron [sudo] password for forge: Reading package lists... Done Building dependency tree Reading state information... Done cron is already the newest version (3.0pl1-136ubuntu1). 0 upgraded, 0 newly installed, 0 to remove and 149 not upgraded. crontab -e no crontab for forge - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/nano <---- easiest 2. /usr/bin/vim.basic 3. /usr/bin/mcedit 4. /usr/bin/vim.tiny 5. /bin/ed Choose 1-5 : 1 crontab: installing new crontab
Now comes the most important part: You need to run a WordPress cron from a WordPress Command Line Interface (WP-CLI). This is how it’s done:
GNU nano 4.8 # Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any'). # # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command */15 * * * * cd /home/forge/yoursite.com/public; /usr/local/bin/wp cron event run --due-now >/dev/null 2>&1
*/15 specifies that wp-cron.php will be run every 15 minutes.
You should not use any http calls as they can be easily blocked but your Cloudflare
*/15 * * * * curl https://yoursite.com/wp-cron.php > /dev/null 2>&1
Here are some more examples of how to use cron’s scheduling:
* * * * *– Cron job runs every minute.
20 * * * *– Run the job 20 minutes after every hour.
0,15,30,45 * * * *– Run cron job every 15 minutes.
*/15 * * * *– Run the command every 15 minutes.
0 4 * * *– Run the command every day at 4:00 AM.
0 4 * * 2-4– Run the command every Tuesday, Wednesday, and Thursday at 4:00 AM.
20,40 */8 * 7-12 *– Run the command on the 20th and 40th minute of every 8th hour every day of the last 6 months of the year.
I found that every 15 minutes is enough for my backup job to be completed. Opposed to many people telling you have to run your
wp-cron.php every minute, I do not find it necessary.
What is >/dev/null 2>&1?
This is the way to execute a program quietly, without any emails, and hide all its output.