I recently had a requirement for a simple database backup using Laravel. After doing a quick search online I couldn't find any articles on this so thought I would share this post.
The article will show you how to backup your database using mysqldump and save the output file to Amazon s3 storage. I am using Laravel 5.1 but I am sure that the below will work on other Laravel versions. I will presume you have already set up your s3 storage disk in config/filesystems.php.
Firstly using the terminal you will need to run:
php artisan make:console BackupDatabase
This will create a console command file in app/Console/Commands named BackupDatabase.php.
We will be using Carbon, Storage, DB and Mail in this class so you need to define these at the top of your document, under the namespace.
use Carbon;
use Storage;
use DB;
use Mail;
Change the signature to:
protected $signature = 'backup:database';
Next you can add a description. Example below:
protected $description = 'Run backup on database and upload to S3';
Now, in the handle method we can add our backup code.
//set filename with date and time of backup
$filename = "backup-" . Carbon\Carbon::now()->format('Y-m-d_H-i-s') . ".sql";
//mysqldump command with account credentials from .env file. storage_path() adds default local storage path
$command = "mysqldump --user=" . env('DB_USERNAME') ." --password=" . env('DB_PASSWORD') . " --host=" . env('DB_HOST') . " " . env('DB_DATABASE') . " > " . storage_path() . "/" . $filename;
$returnVar = NULL;
$output = NULL;
//exec command allows you to run terminal commands from php
exec($command, $output, $returnVar);
//if nothing (error) is returned
if(!$returnVar){
//get mysqldump output file from local storage
$getFile = Storage::disk('local')->get($filename);
// put file in backups directory on s3 storage
Storage::disk('s3')->put("backups/" . $filename, $getFile);
// delete local copy
Storage::disk('local')->delete($filename);
}else{
// if there is an error send an email
Mail::raw('There has been an error backing up the database.', function ($message) {
$message->to("rich@example.com", "Rich")->subject("Backup Error");
});
}
If you have a larage database it if often a good idea to gzip the mysqldump to save space on your cloud storage. To do this add a .gz to the end of the filename and change the mysqldump to:
$command = "mysqldump --user=" . env('DB_USERNAME') ." --password=" . env('DB_PASSWORD') . " --host=" . env('DB_HOST') . " " . env('DB_DATABASE') . " | gzip > " . storage_path() . "/" . $filename;
Finally open app/Console/kernal.php and add your class to the protected commands.
protected $commands = [
\App\Console\Commands\Inspire::class,
\App\Console\Commands\BackupDatabase::class,
];
You can now type
php artisan backup:database
in the terminal to run your backup.
It is now really easy to schedule your backup to run automatically. To run your backup daily at midnight add the below, inside the schedule method of kernal.php.
$schedule->command('backup:database')->daily();
For more scheduling options please take a look at laravel.com
Backups will be saved in the backups directory until you stop the scheduled task. To keep your backups directory tidy and save some space take a look at my article on removing old backups with Laravel.
Files for this article can be found on GitHub.