Laravel
Task Scheduler
Laravel Task Scheduler with Docker
Run Laravel's task scheduler by using the schedule:work command. This runs the scheduler in the foreground and checks for scheduled tasks every minute—perfect for containers.
Want to skip the setup? Spin Pro handles Laravel schedulers on your VPS with Docker and zero-downtime deployments—all configured for you.
Why not use cron?
Unlike traditional server setups, we don't use
cron in containers. Instead, Laravel's schedule:work command keeps the process running in the foreground and checks for tasks every minute. You define the actual schedule (daily, hourly, etc.) in your Laravel application using scheduled tasks.Docker Compose example
This example runs a dedicated scheduler container using the same image as your web service. Use the full path to Artisan (/var/www/html/artisan) when defining the container command.
Key points:
- Use the same image for both your web and scheduler services
- Set
SIGTERMas the stop signal for graceful shutdown (especially forfpm-apacheandfpm-nginx) - Include a health check to monitor scheduler status
- Define your actual schedule times in Laravel, not in Docker
compose.yml
services:
php:
image: my/laravel-app
task:
image: my/laravel-app
command: ["php", "/var/www/html/artisan", "schedule:work"]
stop_signal: SIGTERM
healthcheck:
test: ["CMD", "healthcheck-schedule"]
start_period: 10s
Defining your schedule in Laravel
Configure your scheduled tasks in Laravel. The file location depends on your Laravel version:
routes/console.php
<?php
use Illuminate\Support\Facades\Schedule;
Schedule::command('app:process-invoices')
->daily() // Run this task once per day
->at('02:00') // At 2:00 AM
->timezone('America/Chicago'); // In the Chicago timezone
Schedule::command('app:process-latefees')
->daily() // Run this task once per day
->at('04:00') // At 4:00 AM
->timezone('America/Chicago'); // In the Chicago timezone
app/Console/Kernel.php
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('process:invoices')->daily()->at('02:00')->timezone('America/Chicago');
$schedule->command('process:latefees')->daily()->at('04:00')->timezone('America/Chicago');
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
Multiple processes in one container: If you're running
fpm-nginx or fpm-apache and you'd like to have everything in a single container, you can write your own S6 Overlay service script to properly manage multiple processes in a single container. Learn more about about this in our Using S6 Overlay guide.