PHP-Worker for Scheduler in Laradock
Tags: laravel, docker, tutorial, supervisor
Published: 2020-03-24 16:29:29

Laravel also has a scheduler functionality to run a command/task on a defined time. It can be every minute, hourly, daily, or even at a certain time. Schedulers commonly used for automatic tasks, such as reporting products/items count daily or sending daily emails. Or if you a developer, you may want to log every kind of data daily for analytic purposes.

PHP-Worker in Laradock still has one functionality to play with. Now it's time for some logging!

## Prerequisites

Everything would be easier to tell if you knew about the [worker](https://dev.to/dendihandian/php-worker-in-laradock-2e4j) first.

__________

## Prepare the scheduler test command

Let's create this artisan command:

`app\Console\Commands\ExampleSchedulerTest.php` :

```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class ExampleSchedulerTest extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'example:scheduler-test {logLevel} {--message=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command for logging schedulers';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $arguments = $this->arguments();
        $options = $this->options();
        $options['message'] = $options['message'] ?? 'lorem ipsum dolor sit amet';

        switch ($arguments['logLevel']) {
            case 'emergency':
                Log::emergency($options['message']);
                break;
            case 'alert':
                Log::alert($options['message']);
                break;
            case 'critical':
                Log::critical($options['message']);
                break;
            case 'error':
                Log::error($options['message']);
                break;
            case 'warning':
                Log::warning($options['message']);
                break;
            case 'notice':
                Log::notice($options['message']);
                break;
            case 'info':
                Log::info($options['message']);
                break;
            case 'debug':
                Log::debug($options['message']);
                break;
            default:
                Log::debug($options['message']);
                break;
        }
    }
}

```

register the command and make some schedulers to the `app\Console\Kernel.php` :

```php
<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

use App\Console\Commands\ExampleSchedulerTest;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        ExampleSchedulerTest::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('example:scheduler-test debug --message="debug everyMinute"')->everyMinute();
        $schedule->command('example:scheduler-test info --message="info everyFiveMinutes"')->everyFiveMinutes();
        $schedule->command('example:scheduler-test notice --message="notice everyTenMinutes"')->everyTenMinutes();
        $schedule->command('example:scheduler-test warning --message="warning everyFifteenMinutes"')->everyFifteenMinutes();
        $schedule->command('example:scheduler-test error --message="error everyThirtyMinutes"')->everyThirtyMinutes();
        $schedule->command('example:scheduler-test critical --message="critical hourly"')->hourly();
        $schedule->command('example:scheduler-test alert --message="alert hourlyAt 17"')->hourlyAt(17);
        $schedule->command('example:scheduler-test emergency --message="emergency daily"')->daily();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

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

you can try the command first to make sure it works, by executing this command in your workspace bash inside your project:
```
php artisan example:scheduler-test debug --message="debug message"
```
_____________

## Setup the scheduler configuration

We still use our example directories:
```
- projects
  |_ my-awesome-laravel-app 
  |_ laradock
```

Look for this `workspace\crontab\laradock` file inside laradock directory.

```
- projects
  |_ my-awesome-laravel-app 
  |_ laradock
     |_ workspace
        |_ crontab
           |_ laradock
```

Then make sure the line inside `workspace\crontab\laradock` is not commented-out. The content should be like this:

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

Further inside laradock directory, you will find this file `php-worker\supervisord.d\laravel-scheduler.conf.example`. Duplicate this file into `my-awesome-laravel-app-scheduler.conf` (the name can be different, as long as you end it with .conf). 

```
- projects
  |_ my-awesome-laravel-app 
  |_ laradock
     |_ php-worker
        |_ supervisord.d
           |_ laravel-scheduler.conf.example
           |_ my-awesome-laravel-app-scheduler.conf
     |_ workspace
        |_ crontab
           |_ laradock
```

Then modify the `my-awesome-laravel-app-scheduler.conf` content into:

```
[program:my-awesome-laravel-app-scheduler]
process_name=%(program_name)s_%(process_num)02d
command=/bin/sh -c "while [ true ]; do (php /var/www/my-awesome-laravel-app/artisan schedule:run --verbose --no-interaction &); sleep 60; done"
autostart=true
autorestart=true
numprocs=1
user=laradock
redirect_stderr=true
```

And that's all for the scheduler configuration.

_____________

## Run or restart the PHP-Worker container

If you haven't run the `php-worker` container, execute this command inside laradock directory:
```
docker-compose up -d php-worker
```

If it's already running, you may want to restart it using this command:

```
docker-compose restart php-worker
```

## Check the Laravel Log

Look for the latest log file inside `storage/logs` in your laravel app, you should see the logs similar to this:

```
[2020-03-23 17:41:00] local.DEBUG: debug everyMinute  
[2020-03-23 17:41:02] local.INFO: info everyFiveMinutes  
[2020-03-23 17:41:04] local.NOTICE: notice everyTenMinutes  
[2020-03-23 17:41:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:42:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:43:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:44:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:45:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:45:56] local.INFO: info everyFiveMinutes  
[2020-03-23 17:45:57] local.WARNING: warning everyFifteenMinutes  
[2020-03-23 17:46:55] local.DEBUG: debug everyMinute  
[2020-03-23 17:47:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:48:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:49:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:50:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:50:56] local.INFO: info everyFiveMinutes  
[2020-03-23 17:50:57] local.NOTICE: notice everyTenMinutes  
[2020-03-23 17:51:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:52:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:53:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:54:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:55:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:55:57] local.INFO: info everyFiveMinutes  
[2020-03-23 17:56:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:57:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:58:56] local.DEBUG: debug everyMinute  
[2020-03-23 17:59:56] local.DEBUG: debug everyMinute  
[2020-03-23 18:00:56] local.DEBUG: debug everyMinute  
[2020-03-23 18:00:58] local.INFO: info everyFiveMinutes  
[2020-03-23 18:00:59] local.NOTICE: notice everyTenMinutes  
[2020-03-23 18:01:00] local.WARNING: warning everyFifteenMinutes  
[2020-03-23 18:01:01] local.ERROR: error everyThirtyMinutes  
[2020-03-23 18:01:02] local.CRITICAL: critical hourly  
```

Have fun exploring the scheduler in Laradock!

_____________

```
laravel version used: 6.0 LTS
```