Configuring cron jobs

A cron job is a scheduled task. Scheduled tasks are managed by a process called cron. The cron process keeps track of what is called a crontab (short for cron table). There is a system wide crontab and there are separate crontabs for each user. These steps will teach you how to add scheduled tasks to a user based crontab.

Your first cron job.

Go to the TERMINAL tab of the environment of your choice. Here you will find a link to open the terminal and the credentials you will need to authenticate. When the terminal is opened, type in this command followed by enter:

crontab -e

You will now see the nano editor which has opened the crontab for the currently logged in user being webapp. The editor contents will look something like this:

# 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

Warning

The text above is a default explanation from the cron package but Hyperlane will not send out emails for cron task output!

The text in the editor already gives you an explanation of how things work together with an example:

0 5 * * 1 tar -zcf /var/backups/home.tgz /home/

In this example you will notice the first five characters separated by a whitespace character (a single space or a tab): these determine the interval the task will be executed at where an asterisk acts as a wildcard. The days of the week range from 0, being Sunday, to 6 being Saturday. The five fields from left to right indicate:

  • minutes
  • hours
  • day of the month
  • month
  • day of the week

This would mean the example above will be executed at:

  • 0 minutes
  • 5 hours
  • every day of the month
  • every month
  • the 1st day of the week: Monday

In short: at 0500H every Monday.

Immediately after the interval you can see the command that will be executed by the cron:

tar -zcf /var/backups/home.tgz /home/

Now let's add our own cron job. You will need to take a few things into account:

  1. Hyperlane uses environment variables which need to be loaded to memory before executing tasks
  2. You will need to make sure that your scheduled tasks are executed in the right directory

These two things can be solved by chaining commands in the crontab file by using a double ampersand &&. The double ampersand will execute the next command only if the first command succeeded which means that it ended with exit code 0. So in order to make sure we have environment variables loaded and are in the right directory before beginning execution, our command will start like this:

. /.victhorious/conf/shell/envvars && cd /vol/site/current/ && #TODO: add actual command

Now we have environment variables loaded and are in our docroot folder, so now we can complete the command with whatever we are planning to execute. Let's say we would want to schedule the Craft CMS Feed Me import on cron.

Executing the Feed Me commands as command line arguments is the best option, but there are two commands to do this successfully:

  1. Queue new data first
  2. Process the queued data

So we need to chain two additional commands. This time we'll be using the semicolon (;) to do it, making our command look like this:

. /.victhorious/conf/shell/envvars && cd /vol/site/current/ && php craft feed-me/feeds/queue 1 --continue-on-error; php craft queue/run

Tip

Unlike the double ampersand, the semicolon will ensure that all commands are executed regardless of their exit code!

Now we still need to build our time interval part. Let's say we want to execute this import every 15 minutes, then we would end up with this crontab line:

*/15 * * * * . /.victhorious/conf/shell/envvars && cd /vol/site/current/ && php craft feed-me/feeds/queue 1 --continue-on-error; php craft queue/run

The */15 could be read as 'all minutes that can be divided by the number 15' which are:

  • minute 0
  • minute 15
  • minute 30
  • minute 45

In short: every 15 minutes.

Tip

If you are having trouble building the proper time syntax for a desired interval, you can make use of the crontab guru to help you out.

Since most commands usually produce output, we will want to drop this output to prevent useless garbage piling up in the form of user alerts about cron jobs.

The way we can do this is redirect the standard output and standard error to /dev/null like this:

*/15 * * * * . /.victhorious/conf/shell/envvars && cd /vol/site/current/ && php craft feed-me/feeds/queue 1 --continue-on-error > /dev/null 2>&1; php craft queue/run > /dev/null 2>&1

Tip

The > /dev/null 2>&1 addition behind each command will send the output to /dev/null while 2>&1 will also redirect stderr to the stdout causing it to end up in /dev/null as well. If you replace > /dev/null with >> /vol/site/cron.log, you will be able to log the output to the /vol/site/cron.log file on disk.

Warning

The percent character (%) has a special meaning in the crontab syntax. We're not going into that in detail here but know that the % sign needs to be escaped if you want to use it. So if you want to log a formatted date with each cron run, you would need to do something like date +\%D-\%T.

Now save the crontab modifications by pressing CTRL+X followed by typing Y and hitting enter.

View installed cron jobs

To quickly view the list of scheduled taks you can simply enter:

crontab -l

This command will output the crontab file for your user to the screen.