How to Schedule Cron Jobs in Laravel and AWS

Cron Job is a scheduled task which is run at a given interval to do a specific task such as sending notifications to users. In this tutorial, you'll learn how to define different schedules in Laravel and how to write just one Cron Job on AWS EC2 to execute all Laravel's scheduled tasks.

You can easily install Laravel framework by running the following Composer command:

$ composer create-project --prefer-dist laravel/laravel test-cron-jobs

No need to say that there are lots of Artisan commands at your disposal and the following one is for creating a job:

$ php artisan make:job SampleJob

After hitting enter, a new folder will be created in the app folder called Jobs which in this case includes SampleJob.php file:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SampleJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct()
    {
        //
    }

    public function handle()
    {
        //
    }
}

As you can see, this class implements ShouldQueue interface which results in putting this job in a queue. In terms of simplicity, let's remove this interface and complete this class as follows:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SampleJob
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct()
    {
        //
    }

    public function handle()
    {
        echo "A Sample Job Is Done";
    }
}

The handle() method, as the name implies, handles our desired task which in this case is just printing a string. Now let's move on to the Kernel class inside the app/console folder:

<?php

namespace App\Console;

use App\Jobs\SampleJob;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    protected $commands = [
        //
    ];

    protected function schedule(Schedule $schedule)
    {
        $schedule->job(new SampleJob())->everyMinute();
    }

    protected function commands()
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }
}

Inside the schedule() method, we have called the job() method on $schedule object and have passed new SampleJob() as its argument and finally the everyMinute() function is chained to execute this task every minute.

To test this scheduled task in the local environment, we just need to run the following Artisan command:

$ php artisan schedule:run
Running scheduled command: App\Jobs\SampleJob
A Sample Job Is Done

When the schedule:run command is run, Laravel evaluates all scheduled tasks and runs the due ones.

As the next step, we just need to add one Cron entry to AWS EC2 server. First, you have to SSH to your server then run the command below:

$ crontab -e
no crontab for ubuntu - 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/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:

If it's your first time using crontab command, you're asked to choose an editor. After choosing a number from 1 to 4 and pressing enter, an editor opens and you can add your Cron Jobs (Note that each Job must be in one line). For example:

* * * * * cd /var/www/test-cron-jobs && php artisan schedule:run >> /dev/null 2>&1

The above Cron Job will be executed every minute; subsequently, the schedule:run command is executed too and the main responsibility in on Laravel's shoulder to see if a scheduled task is due or not (To get a good understanding how * * * * * works, refer to crontab.guru).

by Behzad Moradi on 2019-10-26

Login to add your comment