omrakhurs's avatar

How to schedule a yearly cron job for a Laravel app on Linux AMI?

I'm trying to set up a cron job for the 1st of January on my AWS EC2 instance for ec2-user. When I do crontab -u ec2-user -l, it shows the following output:

* * * * * usr/bin/php /var/www/html/artisan schedule:run >> /dev/null 2>&1

But even though the following was set up in Kernel.php, the job never fired:

protected $commands = [
    // Commands\Inspire::class,
    Commands\TestYearlyJob::class,
];

protected function schedule(Schedule $schedule)
{
    $schedule->command('table:test-yearly-job')->cron('0 0 1 1 *')
       ->timezone('Europe/London')
       ->appendOutputTo('../taskscheduler.log');
}

The command itself runs from Artisan (I've double checked), so its logic is fine.

I'm wondering if there is a way to do it with the ->yearly()->at() scheduling option? Or perhaps with a closure truth test? But I'm not sure what to put in there for a when() statement. Please help.

0 likes
5 replies
jekinney's avatar

This is my opinion: yearly is pretty crazy long time obviously. Something like that I would fire at least once a month. The command would actually check if it's been a year since etc to see if it actually executes what code needs to. In other words the when() is used in the command logic/code and not scheduler. Though redundantcey isn't always a bad thing.

I also log each command that fires into a db table with data like: actually fired, actually executed, exacuted success or fail (error) and any applicable output. Also I run a scheduled task for queue listen etc. so I add this in for any app that runs at least a queue. This will log if the queue was or wasn't running.

Yearly is an option too.

https://laravel.com/docs/5.3/scheduling#schedule-frequency-options

Make sure the cron is set and running from the docs. (Copy and paste).

omrakhurs's avatar

On my dev machine, it works perfectly with the same exact code, but not on AWS, even though there is a crontab for the user when do crontab -e.

The log on my dev machine gives the expected information. I will use your recommendation and put it all into a table once I've managed to fix the issue.

dtunes's avatar
dtunes
Best Answer
Level 5

Hi,

so you're adding the cron to run under ec2-user? make sure you're running the command under the user with sufficient access to your app files, e.g. nginx or www-data.

I normally stick with /etc/crontab

* * * * * nginx usr/bin/php /var/www/html/artisan schedule:run >> /dev/null 2>&1
omrakhurs's avatar

@dtunes , how does adding nginx or www-data (or, /etc/crontab) change the access to app files? Asking as a newb here.

dtunes's avatar

You basically should run the script, in this case, artisan under a user which has sufficient permissions to run your scheduled task.

For instance, I see that you're using ->appendOutputTo()...

run the following command under the directory that taskscheduler.log lives.

ls -al
-rw-r--r-- 1 nginx    ec2-user  192 Feb 20 20:00 taskscheduler.log

If it looks like the above, then it means that ec2-user only has read permissions on that file, now, I'm not sure if this will solve your problem, since I'm not sure if the task will still run even if the script doesn't have access to write to the file, or if it will squawk, also, I haven't tried the yealy() option yet, but checking the api docs looks fine to me.

I hope this helps, also, I'm not sure how you're testing the yearly() task, there should a log such as below somewhere..

Jan 1 00:00:01 ec2ip CROND[7461]: (nginx) CMD (php /var/www/app/current/artisan schedule:run >> /dev/null 2>&1)
1 like

Please or to participate in this conversation.