I need to learn how to work with cron jobs in Laravel..As I can see the documentation does not specify this part.I have found a tutorial but it is about Laravel-3. Can you give me some advice on how to schedule a cron job running once a day..?Is there any tutorial about that issue?
My code so far is the following :
JobDaemon.php :
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
class JobDaemon extends Command {
/**
* The console command name.
*
* #var string
*/
protected $name = 'job-daemon';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Get all recent jobs once a day.';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return void
*/
public function fire()
{
$this->info('fired');
}
/**
* Get the console command arguments.
*
* #return array
*/
protected function getArguments()
{
return array(
//array('example', InputArgument::REQUIRED, 'An example argument.'),
);
}
/**
* Get the console command options.
*
* #return array
*/
protected function getOptions()
{
return array(
//array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null),
);
}
}
I used the following command to set it up
php artisan command:make JobDaemon
And my artisan file is the following:
<?php
Artisan::add(new JobDaemon);
I get the following from my console...
johnnemo#johnnemo:/opt/lampp/htdocs/e-support-uop$ tail -f /var/log/syslog | grep -i cron
Jan 1 18:31:09 johnnemo crontab[4484]: (johnnemo) REPLACE (johnnemo)
Jan 1 18:31:09 johnnemo crontab[4484]: (johnnemo) END EDIT (johnnemo)
Jan 1 18:35:01 johnnemo CRON[5054]: (johnnemo) CMD (php /opt/lampp/htdocs/e-support-uop/artisan job-daemon)
Jan 1 18:35:02 johnnemo CRON[5053]: (CRON) info (No MTA installed, discarding output)
Jan 1 18:39:01 johnnemo CRON[5064]: (root) CMD ( [ -x /usr/lib/php5/maxlifetime ] && [ -x /usr/lib/php5/sessionclean ] && [ -d /var/lib/php5 ] && /usr/lib/php5/sessionclean /var/lib/php5 $(/usr/lib/php5/maxlifetime))
Jan 1 18:40:01 johnnemo CRON[5076]: (johnnemo) CMD (php /opt/lampp/htdocs/e-support-uop/artisan job-daemon)
Jan 1 18:40:01 johnnemo CRON[5075]: (CRON) info (No MTA installed, discarding output)
First you need to make sure your new command is up, so if you run
php artisan list
'job-daemon' must be in the list of commands
Then you test it:
php artisan job-daemon
Does it work? Cool, now you can set an editor of your own:
export EDITOR=nano
Open the crontab with it:
[sudo] crontab -e
Execute type to the the correct path for your php:
type php
And you should get something like
php is hashed (/opt/lampp/bin/php)
So your php executable is at
/opt/lampp/bin/php
This will open and editor with the current cron jobs, sudo is optional to open the root crontab, just add a line with yours:
25 10 * * * /opt/lampp/bin/php /whatever/directory/your/site/is/artisan job-daemon
This will run your command everyday at 10:25AM.
To execute it every 5 minutes you do
*/5 * * * * /opt/lampp/bin/php /whatever/directory/your/site/is/artisan job-daemon
Then you tail the syslog to see it running:
tail -f /var/log/syslog | grep -i cron
And you should see something like
Jan 1 10:25:01 server CRON[19451]: (root) CMD (php /var/www/<siteName>/artisan job-daemon)
In your command you cann't really print things on the screen, you won't see them printing, so to test you have to, for instance, save something to a file:
public function fire()
{
File::append('/tmp/laravel.txt', "fired\n");
Log::info('fired');
}
And then
tail -f /tmp/laravel.txt
To see the results in realtime.
I had a similar question to the OP, Antonio's answer got me most of the way there, but not 100%. I was attempting to schedule the job from the cPanel CRON Jobs page, and encountered either 404 errors or no error, but no success either. For me, the key was the following:
Putty into my server, run the command:
php artisan list
Ensure my command was listed
Run the next command:
type php
For me, the output was "php is hashed (/usr/local/bin/php)"
When creating the CRON command, I had to use the qualified path. In addition, since artisan isn't globally available, you also have to use a qualified path to where it's available. For me, this was the laravel folder of my site. The last gotcha was that I had to prefix the actual artisan command with "command:"
In the end, I was able to schedule a laravel command via cPanel's CRON Jobs page using the following command:
/usr/local/bin/php /home/sitename/public_html/laravel/artisan command:TotalMadnessUpdateResultsCommand
Another common gotcha is not adding the following to your artisan.php file:
Artisan::add(new TotalMadnessUpdateResultsCommand);
Related
I'm running a Laravel PHP application as a container on AWS ECS. The container runs both php-fpm and nginx in the same container.
I didn't write the application, I'm a DevOps guy, but I'm struggling with a Command that I added recently to generate a sitemap.xml.
The important bits of the application's Dockerfile is an ENTRYPOINT script which contains this...
nginx -g "daemon off;" &
echo "--- Clearing artisan cache"
yes | php artisan config:clear
echo "--- Running migrations"
yes | php artisan migrate
echo "--- Seeding database"
yes | php artisan db:seed
echo "--- Running final container command"
exec "$#"
And its CMD looks like this:
CMD ["php-fpm", "--nodaemonize", "--force-stderr"]
The PHP command I C&P'd from the Spatie sitemap generator examples looks like this:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Spatie\Sitemap\SitemapGenerator;
class GenerateSitemap extends Command
{
/**
* The console command name.
*
* #var string
*/
protected $signature = 'sitemap:generate';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Generate the sitemap.';
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
// modify this to your own needs
SitemapGenerator::create(config('app.url'))
->writeToFile(public_path('sitemap.xml'));
}
}
If I exec into the running container and run php artisan schedule:list I see the following output:
0 0 * * * php artisan sitemap:generate ........ Next Due: 12 hours from now
The container has been running for nearly a week with this command, but if I run find / -name "sitemap.xml" I see no results and if I view mywebsite.co.uk/sitemap.xml I get no response.
The main problem I'm having is that I have no idea how to diagnose any problems with this command. I've got Sentry configured correctly (it reports exceptions - but nothing related to this command) and my container logs only appear to show Nginx access logs.
If I navigate through the container's file structure, I can't see any PHP logs at all. I'm wondering if the PHP logs are working as expected, but the command is just failing silently?
Any thoughts on the command itself or the container PHP logs would be greatly appreciated.
I have a cron set on ubuntu to run some Laravel scheduled commands. It's running sometimes and stopping at random times. last week it did not run the commands for the whole week, the it started to run again yesterday. This morning it stopped again. I have tried everything but nothing seems to be solving the issue. What am i missing?
Here is the cron:
*/15 * * * * ubuntu cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1
And Here is my Kernel.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 = [
\App\Console\Commands\TrackData::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('data:track')->withoutOverlapping()
->everyFifteenMinutes()->appendOutputTo(storage_path().'/logs/laravel_output.log');
$schedule->command('queue:listen')->withoutOverlapping()
->everyFifteenMinutes()->appendOutputTo(storage_path().'/logs/laravel_output.log');
$schedule->command('delete:oldxml')->withoutOverlapping()
->dailyAt('00:01');
// $schedule->command('sitemap:generate')
// ->daily();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
I've tried everything but nothing seems to solve the problem. What am i missing
it might be many reasons for this kind of problem where your crontab suddenly stopped working.
it might be related to crontab user. to solve the problem, you can try to delete all crontabs for both root and other users.
You can catch the script error into a log file for better investigation as following.
*/15 * * * * ubuntu cd /var/www/html && php artisan schedule:run >> /tmp/script.log 2>&1
it might be related to the PHP config. Your script may run longer than your php.ini's max_execution_time and also check set_time_limit()
You can check cron log by using this command tail -fn 100 /var/log/cron
it might occur due to script file permission and ownership of script files. so make sure you give proper permission to the script file.
chmod +x yourscript.sh chown root:root yourscript.sh
it might be related to OS. Maybe your webserver disk is full or an OS that can't spawn new threads.
Maybe your script has begun to overlap themselves and */15 * * * * is not enough. you can try to increase time to */30 * * * *
I have this simple command in symfony :
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class AuctionEndCommand extends Command
{
protected function configure()
{
error_log(print_r('test',true), 3, "/tmp/error.log");
$this->setName('desktop:auction_end')->setDescription('Execute when auction is end.')->setHelp("Identify winners for auctions");
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// outputs multiple lines to the console (adding "\n" at the end of each line)
$output->writeln([
'User Creator',
'============',
'',
]);
// outputs a message followed by a "\n"
$output->writeln('Whoa!');
// outputs a message without adding a "\n" at the end of the line
$output->write('You are about to ');
$output->write('create a user.');
}
}
Now when I execute : /var/www/myProject/bin/console desktop:auction_end this command works fine. But when I try to execute as a cron in linux this script doesn't start :
In linux as sudo I did :
nano crontab -e, and the cron :
* * * * * /usr/bin/php /var/www/myProject/bin/console desktop:auction_end > /dev/null
What I'm doing wrong, can you help me please ? Thx in advance and sorry for my english
I can keep it very short. You will need to use PHP to execute the console.
* * * * * php -q /usr/bin/php /var/www/myProject/bin/console desktop:auction_end > /dev/null
Writing the output of a cron job that you are testing to a file will help you debug errors. All output is now lost in the void :)
* * * * * php -q /usr/bin/php /var/www/myProject/bin/console desktop:auction_end > /home/<user>/crons/auction_end.cron.txt
Edit
It might be that your php should be used as absolute path.
* * * * * /path/to/php /path/to/bin/console symfony:command
Or even by specifying the user to execute the command with:
* * * * * root /usr/bin/php /path/to/bin/console command:to:execute
Also make sure that the root user has permission to execute files in your symfony project.
What user are you executing the cron as?
Symfony requires write access to ( depending on version ) app/cache && app/log(s) || var/cache && var/log(s) if the user you're executing the command as doesn't have write access to the directories you're trying to write to then your operation will fail.
A good way of fixing this would be to check the error logs, either in var/log(s) app/log(s) or check the apache2 error logs in /var/log/apache2/error.log I would guess one of these logs will contain a hint to your problem.
If you run it as root, does that work:
* * * * * root php /var/www/myProject/bin/console desktop:auction_end > /dev/null
See if that works.
My laravel version is 5.0.28, I build on cloud9, and I added this command to my cron:
#!/bin/bash
PATH=/usr/bin
* * * * * php /home/ubuntu/workspace/app/artisan scheduled:run 1>> /dev/null 2>&1
I added this code on my Kernel.php. I referenced this site: https://laravel-news.com/2014/11/laravel-5-scheduler/
<?php namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Http\Controllers\ApiController;
class Kernel extends ConsoleKernel {
protected $commands = [
'App\Console\Commands\Inspire',
];
protected function schedule(Schedule $schedule)
{
$schedule->call('ApiController#test_job')->hourly();
}
}
I waited and it still didn't work, so I tried to use the command php artisan schedule:run, and I got: No scheduled commands are ready to run.
I searched and found this answer: Laravel 5 "Class does not exist" when using the scheduler
So I modified my code. Also, this code had no specified time, so I modified my cron to specify a time, but it still doesn't work. I have no more ideas. please help. Thanks.
code
$schedule->call(join('#', [ApiController::class, 'test_job']));
cron
0 0,3,6,9,12,15,18,21 * * * php /home/ubuntu/workspace/app/artisan schedule:run 1>> /dev/null 2>&1
30 1,4,7,10,13,16,19,22 * * * php /home/ubuntu/workspace/app/artisan schedule:run 1>> /dev/null 2>&1
first to Test if cron is running in your server or localhost type:
> sudo service cron status
if not installed:
> sudo apt-get install cron
to enable laravel's scheduler:
> crontab -e
and you can select an editor if not vim opens directly. Be sure to enter there this line at the bottom:
* * * * * php /path_from_root_to_laravel_proj_folder/artisan schedule:run 1>> /dev/null 2>&1
to Test if you have setup inside laravel the scheduler right, run this from your projects folder:
>php artisan schedule:run
this should execute the tasks and tell you what is doing.
Laravel scheduler works with commands, not with controller methods:
create command:
php artisan make:command PurchasePodcast
edit command:
namespace App\Console\Commands;
use Illuminate\Console\Command;
class PurchasePodcast extends Command
{
protected $name = 'purchase:podcast';
public function fire()
{
// do stuff here
}
}
add command to Console\Kernel.php:
protected $commands = [
'App\Console\Commands\PurchasePodcast',
];
use command in scheduler:
$schedule->command('purchase:podcast')->hourly();
In my case, the scheduler actually run but encountered an error because of lower php version, beside artisan path (which is your project folder), I had to set the php path as below:
* * * * * /path_to_php_folder/bin/php /path_from_root_to_laravel_proj_folder/artisan schedule:run 1>> /dev/null 2>&1
There are several aspects to find the cause:
First, check whether the 'timezone' in config/app.php is set properly. Laravel will reset the timezone even though you already configured it in php.ini.
Secondly, check that crontab is working as expected. When you get the message "No schedule to be ready", it means your crontab is running and can detect the php and artisan command.
In order to complete #limonte's answer the create Console Command is the following:
php artisan make:console CampaignsCollect --command=campaigns:collect
Reference here: link
I have custom Artisan commands that run locally as well as on my production server when I am SSH'd in, but are unavailable to any cron jobs. I've even tried running it as the user the cron job runs as and it works fine from my console.
When I run php artisan in the above settings, my custom commands are listed and available. However, they are not listed when I run php artisan as a cron job.
Furthermore, trying to run the custom command php artisan subjects:calculate as a cron job results in the following error:
[InvalidArgumentException]
There are no commands defined in the "subjects" namespace.
I was fighting with the same error and I found the solution.
First failed attempts
*/5 * * * * /usr/bin/php /home/mysite/public_html/artisan my:command
*/5 * * * * php /home/mysite/public_html/artisan my:command
Solution
*/5 * * * * /usr/local/bin/php /home/mysite/public_html/artisan my:command
Be sure to add the command to app/start/artisan.php file:
Artisan::add(new SubjectsCommand);
or if you are using the IOC container:
Artisan:resolve('SubjectsCommand');
Then run the CronJob from the folder of the app:
00 09-18 * * 1-5 php /path/to/yourapp/artisan subjects:calculate
or
00 09-18 * * 1-5 /usr/bin/php /path/to/yourapp/artisan subjects:calculate
At least for me that worked:
class Kernel extends ConsoleKernel
{
protected $commands = [
// Commands\YourCommand::class,
];
}
Just added my command to the list of command kernel.
You probable need to make sure artisan is running from the correct directory
cd /path/to/yourproject && php artisan subjects:calculate