Simple Laravel Backup

Written by Rich Banks on 20th Dec, 2015

Laravel

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.

  • adam

    • 2 years ago

    Great article, Richard. Short and to the point like the rest of your posts! I wanted to add that developers can take a shortcut to all these steps by using simplebackups.io if they prefer a simpler solution! We built simplebackups.io with the single goal of making Laravel backups as well as database backups very simple, with notifications and a central dashboard to manage all your websites. Check it out and give us feedback! Adam from SimpleBackups