Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds note for using cron #393

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 92 additions & 1 deletion docs/content/docs/4.laravel/2.laravel-task-scheduler.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,94 @@ Running a Laravel task scheduler with Docker can be a little different from the
## More detail
We need to run the [schedule:work](https://laravel.com/docs/11.x/scheduling#running-the-scheduler-locally) command from Laravel. Although the docs say "Running the scheduler locally", this is what we want in production. It will run the scheduler in the foreground and execute it every minute. You can configure your Laravel app for the exact time that a command should run through a [scheduled task](https://laravel.com/docs/11.x/scheduling#scheduling-artisan-commands).

## Using cron
Laravel versions prior to 8.x don't have the `schedule:work` command, as [noted by this PR](https://github.com/laravel/framework/pull/34618). This may be also the case for non-Laravel applications that require external scheduling or do not ship with and scheduler process.

A non-invasive alternative is to incorporate the command manually in your application, which basically runs the scheduler each second on a loop.

::codepanel
---
label: A command that runs the Laravel Scheduler
---
```php
namespace App\Console;

use Illuminate\Console\Command;
use Illuminate\Support\Carbon;

class ScheduleWorkCommand extends Command
{
protected $name = 'schedule:work';
protected $description = 'Start the schedule worker';

public function handle()
{
$this->info('Starting the Schedule worker.');

while (true) {
if (Carbon::now()->second === 0) {
$this->call('schedule:run');
}

sleep(1);
}
}
}
```
::

If creating a command is not an alternative, you will need to install `cron`, and add a cron entry to run the Laravel Scheduler each second.

The best place to prepare cron would be in the production image, or before installing your application inside the container. Alpine images use Busybox, which includes `crond` out of the box, so there is no need to install it when using Alpine.

::codepanel
---
label: Installing cron and adding a Laravel Scheduler entry
---
```dockerfile
# ... Prior build steps

# Ensure we're root to install and prepare cron.
USER root

# Install cron on Debian
RUN apt-get update && apt-get -y --no-install-recommends install cron && \
rm -rf /var/lib/apit/lists/*

# Set Laravel's Scheduler in the container default crontab file running as the "www-data" user
RUN printf "* * * * * www-data php /var/www/html/artisan schedule:run\n" >> /etc/crontab

# Copy our app files as www-data (33:33)
COPY --chown=www-data:www-data . /var/www/html

# Ensure next instructions run as the unpriviledged "www-data" user
USER www-data

# Install the application
RUN composer install
```
::

In your Docker Compose file, you will need to call `cron` in the foreground. [On Debian](https://manpages.debian.org/bookworm/cron/cron.8.en.html), this is done with `/usr/sbin/cron -f -L 15`. On Alpine, [BusyBox's `crond`](https://busybox.net/downloads/BusyBox.html#crond) does the job as `/usr/sbin/crond -f -l 0`. Both of these commands will run the process with verbose output.

::code-panel
---
label: Calling the Laravel Scheduler through cron in Docker Compose File
---
```yaml
services:
php:
image: myself/laravel-app
environment:
PHP_FPM_POOL_NAME: "my-app_php"

task:
image: myself/laravel-app
command: ["/usr/sbin/cron", "-f", "-L", "15"]
environment:
PHP_FPM_POOL_NAME: "my-app_task"
```
::

## Examples
Here is a simplified example of how you can achieve this with Docker Compose:
Expand Down Expand Up @@ -97,7 +185,10 @@ class Kernel extends ConsoleKernel
```
::


=======

## Get Up and Running The Easy Way
We do all the heavy lifting for you with Spin Pro. It's as easy as selecting it in a menu and we'll configure everything else for you. Learn how easy it is to get up and running with the Task Scheduler on Spin Pro.

[Learn more about Laravel Task Scheduler + Spin Pro →](https://getspin.pro/docs/services/laravel-scheduler)
[Learn more about Laravel Task Scheduler + Spin Pro →](https://getspin.pro/docs/services/laravel-scheduler)