Laravel database backup schedule - laravel

I am trying to set up a scheduler for weekly database backup in laravel. I have created a command and filled out some data like the command itself and description, and registered it in the console kernel as well. The issue is that the file never gets created and/or stored in storage.
This is the part of the code where is the command:
public function handle()
{
Log::info('Database backup completed.');
$filename = 'mysite' . Carbon::now()->format('Y-m-d') . ".gz";
$command = "mysqldump --user=" . env('DB_USERNAME') ." --password=" . env('DB_PASSWORD') . " --host=" . env('DB_HOST') . " " . env('DB_DATABASE') . " | gzip > " . storage_path() . "/app/backup/" . $filename;
$returnVar = NULL;
$output = NULL;
exec($command, $output, $returnVar);
}
This is the kernel part:
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
OtherCron::class,
DatabaseBackupCron::class,
];
/**
* Define the application's command schedule.
*
* #param Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('othercron')->dailyAt('00:00');
$schedule->command('database-backup:cron')->everyFiveMinutes();
}
Note: I have used "->everyFiveMinutes()" just for testing purposes :)

You could use a ready-made lib for that:
github.com/spresnac/laravel-artisan-database-helper
and then just call the command in the scheduler as you like ;)
You can also set the full path to your mysqldump binary, if it's not in your path ;)

I tried your code, it is working for me, the only difference is in Kernel, I wrote like this.
protected $commands = [
'App\Console\Commands\DatabaseBackUp'
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
//some other commands
$schedule->command('database:backup')->weekly();
}
now the moment I run php artisan database:backup a file with the extension .zp created in the storage folder

php artisan make:command DatabaseBackUp
Use this command make databasebackup file.
app/Console/Commands/DatabaseBackUp.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
class DatabaseBackUp extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'database:backup';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return int
*/
public function handle()
{
$filename = "backup-" . Carbon::now()->format('Y-m-d') . ".gz";
$command = "mysqldump --user=" . env('DB_USERNAME') ." --password=" . env('DB_PASSWORD') . " --host=" . env('DB_HOST') . " " . env('DB_DATABASE') . " | gzip > " . storage_path() . "/app/backup/" . $filename;
$returnVar = NULL;
$output = NULL;
exec($command, $output, $returnVar);
}
}
In this step, we need to create "backup" folder in your storage folder. you must have to create "backup" on following path:
storage/app/backup
Now, in this step, we need to schedule our created command. so let's update kernel file as like bellow:
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 = [
'App\Console\Commands\DatabaseBackUp'
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('database:backup')->daily();
}
/**
* Register the commands for the application.
*
* #return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
you can check following command to getting database backup with this command:
php artisan database:backup
t will create one backup file on your backup folder. you can check there.
Now, we are ready to setup cron on our server.
At last you can manage this command on scheduling task, you have to add a single entry to your server’s crontab file:
Run following command:
crontab -e

Related

How to do daily database backup for PostgreSQL using Laravel?

I have seen this tutorial online https://www.itsolutionstuff.com/post/laravel-automatic-daily-database-backup-tutorialexample.html on how to backup database daily for mysql. How to do this in postgreSQL?
MySQL
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Carbon\Carbon;
class DatabaseBackUp extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'database:backup';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return int
*/
public function handle()
{
$filename = "backup-" . Carbon::now()->format('Y-m-d') . ".gz";
$command = "mysqldump --user=" . env('DB_USERNAME') ." --password=" . env('DB_PASSWORD') . " --host=" . env('DB_HOST') . " " . env('DB_DATABASE') . " | gzip > " . storage_path() . "/app/backup/" . $filename;
$returnVar = NULL;
$output = NULL;
exec($command, $output, $returnVar);
}
}
This backup package is your friend ;)

Run external command via Laravel Artisan Console

I'm looking to execute psexec from Laravel to execute some remote command and I'd like to use the Artisan Console to do so (for now). Ideally, I'd like to navigate to a url and the command would be issued (something i'd implement after this initial stage).
What I have so far is:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class RestartSplunk extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'splunk:restart {host}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Restart Splunk instance on given host';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$host = $this->argument('host');
$bar = $this->output->createProgressBar();
if ($this->confirm('Are you sure you\'d like to restart ' . $host )) {
$this->info('Restarting ' . $host . '...');
}
}
}
If someone has implemented this or can share some resources to accomplish this it'd me much appreciated.
I have found my answer The Process Component in Symphony.

How to clear all Log files data using Monolog in Laravel

How to empty log files data before adding new contents to it.
Using Monolog for saving all logs inside
storage/app/logs/*
You can use rm command through ssh to remove all logs:
rm storage/logs/laravel-*.log. Use * as wildcard to remove all logs if they have suffixes.
Or you can add custom code within Controller method only for admins of app:
$files = glob('storage/logs/laravel*.log');
foreach($files as $file){
if(file_exists($file)){
unlink($file);
}
}
Or create a console command. Depending on version, below 5.3 use for example:
php artisan make:console logsClear --command=logs:clear
For versions 5.3 and above
php artisan make:command logsClear
add signature within command class if it doesn't exist.
protected $signature = 'logs:clear';
Add your class in Console/Kernel.php, in protected $commands array ( note that your code varies upon customization for your app):
<?php
namespace App\Console;
use App\Console\Commands\logsClear;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Utils\ShareHelper;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
logsClear::class,
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
}
}
You should add then custom code in handle() of logsClear class
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class logsClear extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'logs:clear';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
//
$files = glob('storage/logs/laravel*.log');
foreach($files as $file){
if(file_exists($file)){
unlink($file);
}
}
}
}
Then run php artisan logs:clear command

Laravel 5.4 - Passing Data from Controller to Artisan Handle

To get things started, I made a custom Artisan Command called MySqlRestore.
It simply restores the database using the dumped sql file.
Here's my MySqlRestore code:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class MySqlRestore extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'db:restore';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Restores database using info from .env';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$sqlfile = //data from controller;
$ds = DIRECTORY_SEPARATOR;
$host = env('DB_HOST');
$username = env('DB_USERNAME');
$password = env('DB_PASSWORD');
$database = env('DB_DATABASE');
$mysqlpath = 'C:\xampp\mysql\bin\mysql';
$path = 'C:\salesandinventory\Backups\\';
$command = sprintf($mysqlpath . ' --user=' . $username . ' --password=' . $password . ' --host=' . $host . ' ' . $database . ' < ' . $path . $sqlfile);
exec($command);
}
}
Now on this line $sqlfile = //data from controller;, I need the data from my controller.
Here's how my controller looks like:
<?php
namespace App\Http\Controllers;
use App\Database;
use Illuminate\Http\Request;
use Artisan;
class DatabaseController extends Controller
{
public function index()
{
return view('database.index');
}
public function restoreDatabase(Request $request)
{
$sqlfile = $request->sqlfile; // the data I need.
Artisan::call('db:restore');
return view('database.index');
}
}
Now I don't have any idea how to pass $sqlfile = $request->sqlfile; this data from my controller into my Artisan handle function.
Data's are passed through the protected $signature using curly braces {dataName}
e.g
protected $signature = 'db:restore {dataName}'
and it is called using
$this->argument('dataName');
In your controller
Artisan::call('db:restore',['test'=> $test]);
namespace App\Console\Commands;
use Illuminate\Console\Command;
class MySqlRestore extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'db:restore {test}';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Restores database using info from .env';
public $sqlFile;
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$sqlfile = $this->argument('test');
$ds = DIRECTORY_SEPARATOR;
$host = env('DB_HOST');
$username = env('DB_USERNAME');
$password = env('DB_PASSWORD');
$database = env('DB_DATABASE');
$mysqlpath = 'C:\xampp\mysql\bin\mysql';
$path = 'C:\salesandinventory\Backups\\';
$command = sprintf($mysqlpath . ' --user=' . $username . ' --password=' . $password . ' --host=' . $host . ' ' . $database . ' < ' . $path . $sqlfile);
exec($command);
}
}
Call it like this
Artisan::call('db:restore',['test'=> $test]);
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class MySqlRestore extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'db:restore';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Restores database using info from .env';
public $sqlFile;
/**
* Create a new command instance.
*
* #return void
*/
public function __construct($sqlFile)
{
$this->sqlFile = $sqlFile;
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
$sqlfile = $this->sqlFile;
$ds = DIRECTORY_SEPARATOR;
$host = env('DB_HOST');
$username = env('DB_USERNAME');
$password = env('DB_PASSWORD');
$database = env('DB_DATABASE');
$mysqlpath = 'C:\xampp\mysql\bin\mysql';
$path = 'C:\salesandinventory\Backups\\';
$command = sprintf($mysqlpath . ' --user=' . $username . ' --password=' . $password . ' --host=' . $host . ' ' . $database . ' < ' . $path . $sqlfile);
exec($command);
}
}
Controller
<?php
namespace App\Http\Controllers;
use App\Database;
use Illuminate\Http\Request;
use Artisan;
class DatabaseController extends Controller
{
public function index()
{
return view('database.index');
}
public function restoreDatabase(Request $request)
{
$sqlfile = $request->sqlfile; // the data I need.
Artisan::call('db:restore',['sqlFile'=>$sqlFile]);
return view('database.index');
}
}
Your controller should not be executing Artisan commands, especially potentially long-running ones like executing a database back-up.
Instead, consider dispatching a queued job that performs the restore. You can then return control to the user and they can get on with things they need to do, instead of keeping a web page open that could possibly timeout and leave the database in a corrupt state.
class DatabaseRestoreController extends Controller
{
public function store(Request $request)
{
dispatch(new RestoreDatabaseJob($request->input('filename')));
return redirect()->back()->withSuccess('Restoring database.');
}
}
And the job class itself:
class RestoreDatabaseJob implements ShouldQueue
{
use InteractsWithQueue;
public $filename;
public function __construct($filename)
{
$this->filename = $filename;
}
public function handle()
{
Artisan::call('db:restore', [
'filename' => $this->filename,
]);
// You can notify user restore completed
// Send email, SMS via notification etc.
}
}

"Best way" to run Laravel queue listen

Currently I'm working on a project where I queue emails to be send. However I wonder what would be the "best way" to run the queue listener. Right now I only know about the nohup way.
However, by using nohup it feels like the queue listener is no part of the application anymore. It's like using the scheduler to make your cronjobs more part of the application.
Are there any other ways to listen the queue and what would be your preference?
Here's what I wrote to achieve this:
app/Console/Commands/QueueProcessListener.php
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class QueueProcessListener extends Command
{
/**
* The name of the command/process we want to monitor. This string will be used both to check to see if the process
* is currently running and to spawn it (The arguments are appended to it).
*
* #var string
*/
protected $command = 'php artisan queue:listen';
/**
* The arguments to pass to the process when spawning it.
*
* #var string
*/
protected $arguments = '--tries=3';
/**
* The signature of the console command. We use the signature when running it through Artisan: php artisan $signature
*
* #var string
*/
protected $signature = 'queue-process-listener';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Monitor the queue listener process to ensure it is always running.';
/**
* Create a new command instance.
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
if (!$this->isProcessRunning($this->command)) {
$this->info("Starting queue listener.");
$this->executeShellCommand($this->command, $this->arguments, true);
} else {
$this->info("Queue listener is running.");
}
}
/**
* Execute a shell command, with the provided arguments, and optionally in the background. Commands that are not run
* in the background will return their output/response.
*
* #param $command
* #param string $arguments
* #param bool $background
* #return string
*/
public function executeShellCommand($command, $arguments = '', $background = false)
{
$command = trim($command);
if (!is_string($command) || empty($command)) {
return null;
}
$arguments = trim($arguments);
$cmd = trim($command . ' ' . $arguments) . ($background ? ' > /dev/null 2>/dev/null &' : '');
return shell_exec($cmd);
}
/**
* Check if a process is running using pgrep.
*
* #param $process
* #return bool
*/
public function isProcessRunning($process)
{
$output = $this->executeShellCommand('pgrep -f "' . $process . '"');
return !empty(trim($output));
}
}
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 = [
Commands\QueueProcessListener::class
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
// Schedule my process listener to run every 5 minutes.
$schedule->command('queue-process-listener')->everyFiveMinutes();
}
}
The documentation tells you exactly how to achieve this:
https://laravel.com/docs/5.3/queues#supervisor-configuration
I'm not sure what you mean by it not being "part of the application". Crons and background worker processes are a standard part of any scale server architecture. There's nothing wrong with using them.
You also should really avoid doing what Jonathon's answer suggests, which is basically writing your own supervisord in php. What if your server reboots? There are battle-tested solutions for this problem, that have been developed and supported by the linux community for a long time now--you should really use them.

Resources