Laravel Task Scheduling on Google App Engine

Viewed 1974

Is there any way to execute php artisan commands on App Engine? I need to set up Laravel's Task Scheduling which requires the following cron job to be set up:

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

but as I looked at cron.yaml documentation, there is no method to execute php file, there seems to be support for only HTTP call to URL.

Can anyway help me with this please?

UPDATE 1 Please do not suggest to call Artisan::handle($command) from within the controller. I need exactly PHP-CLI version of artisan

3 Answers

Apologies for pinging everybody following this thread, but thought I'd offer another solution. This might be more of a discussion point, and very open to hear your thoughts on this

Artisan offers a schedule:work command: (Emphasis mine)

Typically, you would not add a scheduler cron entry to your local development machine. Instead you may use the schedule:work Artisan command. This command will run in the foreground and invoke the scheduler every minute until you terminate the command

We're currently using GAE for a Laravel project, and having success with overwriting the supervisiord configuration as described in the Google App Engine docs. That is, specifying the supervisord_conf_override key under runtime_config in app.yaml, which references a stock standard supervisord configuration file in your source code.

So.. You could provide a supervisord configuration, so it monitors a php artisan schedule:work command. For example:

[supervisord]
nodaemon = true
logfile = /dev/null
logfile_maxbytes = 0
pidfile = /var/run/supervisord.pid

[program:laravel-schedule-worker]
command = php %(ENV_APP_DIR)s/artisan schedule:work
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes=0
user = www-data
autostart = true
autorestart = true
priority = 5
stopwaitsecs = 20

[supervisorctl]

The benefit of this of course is not needing to go as far as shell_exec(...), however from my understanding, the runtime_config key is only available in GAE 'Flexible' environments. So if you're on the 'Standard' environment, then the currently accepted answer would be the way to go.

The Laravel docs describe the schedule:work command as a command to be used in local environments, however I don't see why this can't be used in production environments... maybe there's something I'm missing?

A simpler solution is to put all of this into 1 route and use Artisan::call() instead of shell_exec().

routes/gae.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Route;

Route::get('scheduler', function (Request $request) {
    if(!$request->hasHeader('X-Appengine-Cron')) {
        return abort(401);
    }
    Artisan::call('schedule:run');
    return response('', 204); // no content
});

then load this routes file in the app/Providers/RouteServiceProvider.php

    public function boot()
    {
        // ...
        $this->routes(function () {
            // ...

            $this->mapGaeRoutes();
        });
    }

    protected function mapGaeRoutes()
    {
        Route::group(base_path('routes/gae.php'));
    }

Or, just throw that one route into routes/web.php and skip the route provider modification.

Authorization

This project from github user stackkit has better security checking, but it only runs jobs, not scheduled tasks. Perhaps Artisan::call('schedule:run') can find it's way into this cloud tasks project.

You can see how this project are authorizing the Oidc token given by google by checking the signature and the issuer (iss claim).

You can trivially examine the Oidc token given by google without verifying the signature, if you could hide a known shared secret in the custom claims for the service account, you could verify that and be given a modicum of security.

Since this is only running artisan schedule, and it's running every minute, the only thing you have to guard against is DoS attack.

https://github.com/stackkit/laravel-google-cloud-tasks-queue/blob/master/src/TaskHandler.php

Related