Laravel queue docs: https://laravel.com/docs/master/queues

Jobs

In this guide, the queue driver will be database, you have to config your application to use database.

php artisan queue:table
QUEUE_CONNECTION=database
php artisan migrate

Usage

Create a new Job

php artisan make:job ProcessHeavyServerTask
<?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;
use Log;
class ProcessHeavyServerTask implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
/**
* Create a new job instance.
*/
public function __construct(
public mixed $param,
public mixed $param_alt,
) {
}
/**
* Execute the job.
*/
public function handle()
{
// Very heavy server task...
Log::debug('Success on job '.now());
}
public function failed(\Throwable $exception)
{
Log::error('Error on job');
}
}

Call job

<?php
class MainController extends Controller
{
public function index()
{
$param = [];
$param_alt = true;
ProcessHeavyServerTask::dispatch($param, $param_alt);
}
}

Execute

If you change anything into your job, you have to re-run the command. And for EVERY deployment, you have to restart supervisor.

Local

php artisan queue:work --queue

Server

Install supervisor.

Replace app-name with the name of your application.

sudo apt install supervisor -y
cd /etc/supervisor/conf.d
touch /etc/supervisor/conf.d/app-name-worker.conf
[program:app-name-worker]
process_name=%(program_name)s_%(process_num)02d
command=php8.1 /home/USER/www/app-name/artisan queue:work database --sleep=3 --tries=3
autostart=true
autorestart=true
user=USER
numprocs=1
redirect_stderr=true
stdout_logfile=/home/USER/www/app-name/storage/logs/worker.log
stopwaitsecs=3600

In /etc/supervisor/supervisord.conf, check if this exist.

[include]
files = /etc/supervisor/conf.d/*.conf

When you create a new config, use these commands.

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start app-name-worker:*

When you deploy a new app version, restart supervisor worker with this command.

sudo supervisorctl restart app-name-worker:*

Example with bookshelves app.

sudo supervisorctl start bookshelves-worker:bookshelves-worker_00
List all workers
supervisorctl

Example of output.

bookshelves-worker:bookshelves-worker_00 RUNNING pid 40598, uptime 0:03:30

Restart it.

sudo supervisorctl start bookshelves-worker:bookshelves-worker_00
Manage restart without sudo
/etc/supervisor/supervisord.conf
[unix_http_server] ; add this line chown = USER:www-data

Now USER can restart supervisor without sudo.

Add it to CI

Add to your CI config or post-merge Git hook.

.gitlab-ci.yml
deploy-job: stage: deploy script: - # ... supervisorctl restart bookshelves-worker:bookshelves-worker_00 only: - main

Schedule

app/Console/Kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Console\Commands\AnyCommand;
class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule)
{
$schedule->command(AnyCommand::class, ['argument', '--option'])->daily();
}
}

Shell commands

app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->exec('node /home/forge/script.js')->daily();
}

Cheatsheet

List schedule

php artisan schedule:list

Run schedule

php artisan schedule:run

Keep schedule running

php artisan schedule:work

Run in production

Set php version into cron with php8.1. Just use crontab.

crontab -e
* * * * * cd /path/to/project && php8.1 artisan schedule:run >> /dev/null 2>&1