Perform daily database backup in laravel

In software development, we need to be ready to handle server crashes or data being mistakenly and this can cause a lot of trouble for the business. So developing a system that takes database backup regularly is considered the best practice.

Database backups are essential for protection against data loss that can disrupt operations and could lead to major problems, especially with E-commerce, ERP, HRMS, or any other system in which data is the backbone.

In this example, we will use mysqldump command line utility which can take backup of all types of tables and provides a command line interface. We will use the exec() function to execute mysqldump command.

Further, we will create an artisan command in Laravel which will take a backup of the database and store it in the file system so whenever we lose some data we retrieve it.

Below are the steps to create automatic database backups in Laravel:

  • Create Artisan Command
  • Registering command to Kernal
  • Testing Our Functionality

Create Artisan Command

First of all, let’s create a new artisan command that will handle the database export process and store an exported file in a file system. To create a new command open the terminal at the root directory and enter the below command:

php artisan make:command DailyBackup

It will create a file at app/Console/Commands/DailyBackup.php. All our database backup functionality will be written here. Let’s open it and modify it as per our requirements.

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Carbon\Carbon;
use Exception;

class DailyBackup extends Command
{
    protected $signature = 'daily:backup';

    protected $description = 'Command will create backup file';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        try{
            $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, $returnVar, $output);

            return 1;
        }catch(Exception $e){
            return 0;
        }
    }
}

In command, we have created a signature and description for it. Into the handle method, we have created the mysql dump command using the .env file database configuration and created the file name using the current time.

Here, we have used the exec() function to execute the database export command. It will export the database backup into a file at our specified location.

Register Command to Kernel

After creating the command we need to register it into Kernel.php. So it can be discovered and run when the cron job is called.

To set the command to run automatically, we need to add it to the schedule function and set the frequency of it. There are plenty of options available with Laravel. You can refer to this link for it. For this example, we will set it to daily.

Make the following changes to the Kernel.php file :

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Console\Commands\DailyBackup;

class Kernel extends ConsoleKernel
{
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('daily:backup')->daily();
    }

    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

In this step, we simply call our Daily backup command to schedule with daily frequency.

Testing our functionality

We can test our functionality using the terminal locally or create a cron job on the server. Here, we will test using a terminal.

To test database backup functionality locally in Laravel, you need to open a terminal and run the below command:

php artisan daily:backup

It will create a backup file to our backup path. This file can be directly imported to any fresh database or we can use it for partial data import. You can set it to send this file directly to a specific user through the mail by modifying the command.

While on the server you can set up a cron job to call Laravel schedule and it performs daily database backup automatically.

Just for testing on the server, you can also create a route that executes our artisan command like the below example:

<?php

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

Route::get('/', function () {
    return view('welcome');
});

Route::get('/daily-backup', function () {
    if(Artisan::call('daily:backup')){
        dd('Database backup created.');
    }else{
        dd('Something went wrong.');
    }
});

Conclusion

Here, we have created daily automatic database backup functionality in Laravel using artisan command and core PHP functions. We can extend it by adding some features like deleting old database backups or sharing database files via mail or more. Feel free to provide feedback or comments.