How to backup laravel app and database?

1934
How to backup your laravel app and database?

In this article, we are going to back up our laravel application along with its database. For this, we will use a package called laravel-backup by Spatie. This package will back up our application files into a zip file including the database.

Need for Backup

Why do we need to back up our application? The main reason for this is that we don’t want to lose any of our files and database. No hosting provider can guarantee the 100% uptime to your server. Popular hosting provider such as DigitalOcean, HostGator, GoDaddy, and others have also been down sometimes.

A small hope to get the latest database despite down server is that some hosting providers also provide database backup feature. The problem to this is that database is backed up weekly not daily. So, when the server is down on last day before backup, then you lose your 6 days data.

Solution

To provide a solution to such problems, we are going to implement this feature. As mentioned, we will use laravel-backup package. This package provides other many features besides backing up files and database. Some of the highlighted features are:

  • Backing up files and database
  • Cleaning up old backups
  • Sending out notifications
  • Monitoring the backups

After the introduction, let’s start implementing in our project.

Project Setup & Migrations

We will backup our fresh laravel application along with its default laravel authentication.
Create Project
Let’s create a fresh projet using composer.

composer create-project laravel/laravel kodementor

Database Setup
After creating project, let’s setup database. For this, create a new database and modify our .env file accordingly.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=kodementor
DB_USERNAME=root
DB_PASSWORD=secret

Migration
We will migrate our default migration files that is used for authentication. To migrate, just run the artisan command:

php artisan migrate

Seeding Database
Let’s seed our users table using tinker. If you are new to tinker package, you can learn about How to use Tinker in Laravel Application. To seed our users table, we will run the following command:

php artisan tinker

// in tinker shell run below command
>>> factory(App\User::class, 20)->create();

Install Package

If you have been following spatie packages, they are pretty much updated about the latest version of everything including PHP and Laravel. So, they have precise requirements for installation of their package. Before installing this version of the package, please make sure that you meet these requirements.

  • Requires PHP 7 or higher
  • Requires Laravel 5.3 or higher
  • Need enough free space for backed zip file
  • Should have mysqldump installed to backup MYSQL DB
  • Should have pg_dump installed to backup Postgre SQL DB
  • Should have mongodump installed to backup Mongo DB
  • Optional guzzlehttp/guzzle package for Slack notification

Let’s install our laravel-backup package. We will install via composer. Run the command below:

composer require spatie/laravel-backup

Publish Configuration

This version (v5) will automatically register its service provider. We will publish config files with the command below:

php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"

This will create a new config file config/backup.php. If you open it, you will find a different configuration option.

 [

        /*
         * The name of this application. You can use this name to monitor
         * the backups.
         */
        'name' => config('app.name'),

        'source' => [

            'files' => [

                /*
                 * The list of directories and files that will be included in the backup.
                 */
                'include' => [
                    base_path(),
                ],

                /*
                 * These directories and files will be excluded from the backup.
                 *
                 * Directories used by the backup process will automatically be excluded.
                 */
                'exclude' => [
                    base_path('vendor'),
                    base_path('node_modules'),
                ],

                /*
                 * Determines if symlinks should be followed.
                 */
                'followLinks' => false,
            ],

            /*
             * The names of the connections to the databases that should be backed up
             * MySQL, PostgreSQL, SQLite and Mongo databases are supported.
             *
             * The content of the database dump may be customized for each connection
             * by adding a 'dump' key to the connection settings in config/database.php.
             * E.g.
             * 'mysql' => [
             *       ...
             *      'dump' => [
             *           'excludeTables' => [
             *                'table_to_exclude_from_backup',
             *                'another_table_to_exclude'
             *            ]
             *       ]
             * ],
             *
             * For a complete list of available customization options, see https://github.com/spatie/db-dumper
             */
            'databases' => [
                'mysql',
            ],
        ],

        /*
         * The database dump can be gzipped to decrease diskspace usage.
         */
        'gzip_database_dump' => false,

        'destination' => [

            /*
             * The filename prefix used for the backup zip file.
             */
            'filename_prefix' => '',

            /*
             * The disk names on which the backups will be stored.
             */
            'disks' => [
                'local',
            ],
        ],

        /*
         * The directory where the temporary files will be stored.
         */
        'temporary_directory' => storage_path('app/backup-temp'),
    ],

    /*
     * You can get notified when specific events occur. Out of the box you can use 'mail' and 'slack'.
     * For Slack you need to install guzzlehttp/guzzle.
     *
     * You can also use your own notification classes, just make sure the class is named after one of
     * the `Spatie\Backup\Events` classes.
     */
    'notifications' => [

        'notifications' => [
            \Spatie\Backup\Notifications\Notifications\BackupHasFailed::class         => ['mail'],
            \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'],
            \Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class        => ['mail'],
            \Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class     => ['mail'],
            \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class   => ['mail'],
            \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class    => ['mail'],
        ],

        /*
         * Here you can specify the notifiable to which the notifications should be sent. The default
         * notifiable will use the variables specified in this config file.
         */
        'notifiable' => \Spatie\Backup\Notifications\Notifiable::class,

        'mail' => [
            'to' => 'vijayrana.me@gmail.com',
        ],

        'slack' => [
            'webhook_url' => '',

            /*
             * If this is set to null the default channel of the webhook will be used.
             */
            'channel' => null,

            'username' => null,

            'icon' => null,

        ],
    ],

    /*
     * Here you can specify which backups should be monitored.
     * If a backup does not meet the specified requirements the
     * UnHealthyBackupWasFound event will be fired.
     */
    'monitorBackups' => [
        [
            'name' => config('app.name'),
            'disks' => ['local'],
            'newestBackupsShouldNotBeOlderThanDays' => 1,
            'storageUsedMayNotBeHigherThanMegabytes' => 5000,
        ],

        /*
        [
            'name' => 'name of the second app',
            'disks' => ['local', 's3'],
            'newestBackupsShouldNotBeOlderThanDays' => 1,
            'storageUsedMayNotBeHigherThanMegabytes' => 5000,
        ],
        */
    ],

    'cleanup' => [
        /*
         * The strategy that will be used to cleanup old backups. The default strategy
         * will keep all backups for a certain amount of days. After that period only
         * a daily backup will be kept. After that period only weekly backups will
         * be kept and so on.
         *
         * No matter how you configure it the default strategy will never
         * delete the newest backup.
         */
        'strategy' => \Spatie\Backup\Tasks\Cleanup\Strategies\DefaultStrategy::class,

        'defaultStrategy' => [

            /*
             * The number of days for which backups must be kept.
             */
            'keepAllBackupsForDays' => 7,

            /*
             * The number of days for which daily backups must be kept.
             */
            'keepDailyBackupsForDays' => 16,

            /*
             * The number of weeks for which one weekly backup must be kept.
             */
            'keepWeeklyBackupsForWeeks' => 8,

            /*
             * The number of months for which one monthly backup must be kept.
             */
            'keepMonthlyBackupsForMonths' => 4,

            /*
             * The number of years for which one yearly backup must be kept.
             */
            'keepYearlyBackupsForYears' => 2,

            /*
             * After cleaning up the backups remove the oldest backup until
             * this amount of megabytes has been reached.
             */
            'deleteOldestBackupsWhenUsingMoreMegabytesThan' => 5000,
        ],
    ],
];
?>

Running Backup

Now, we can start backing up our application. To backup all the files including database, run the following command:

php artisan backup:run

This will output as screenshot below:
How to backup your laravel app and database - kodementor

This will backup our files in the directory specified in configuration. By default, it will export to App\storage\app\Laravel directory. We can also only backup application files without database with the following command:

php artisan backup:run --

Cleaning Backup

At some point of time, we may need to clean up our old backed storage. For this, run the command below:

php artisan backup:clean

Output:
How to backup your laravel app and database - kodementor

You may see that the running the command did not delete your old files. This is because deleting old backup files is a bit tricky. You need to understand the basic rules for this. The rules for cleaning old backups can be found in this link. We will get a notification email when something goes wrong during this process.

Monitoring Health of Backup

Another useful feature of this package is that we can check the health of the backed up files. Normally, if the backup file is too far old or if the amount of storage space required for all backups is not available, then the backup is considered to be unhealthy.

We can check the status of our backup using the following command:

php artisan backup:monitor

As stated in the official documentation, “To install the monitor follow the regular installation instructions. Instead of scheduling the backup:run and backup:clean commands, you should schedule the monitor command”.

//app/Console/Kernel.php

protected function schedule(Schedule $schedule)
{
   $schedule->command('backup:monitor')->daily()->at('03:00');
}

Besides this, you can configure more monitor settings from the configuration file.

// app/config/backup.php

/*
 * Here you can specify which backups should be monitored.
 * If a backup does not meet the specified requirements the
 * UnHealthyBackupWasFound event will be fired.
 */
'monitorBackups' => [
    [
        'name' => config('app.name'),
        'disks' => ['local'],
        'newestBackupsShouldNotBeOlderThanDays' => 1,
        'storageUsedMayNotBeHigherThanMegabytes' => 5000,
    ],

    /*
    [
        'name' => 'name of the second app',
        'disks' => ['local', 's3'],
        'newestBackupsShouldNotBeOlderThanDays' => 1,
        'storageUsedMayNotBeHigherThanMegabytes' => 5000,
    ],
    */
],

Notification

The laravel-backup package send notifications to user through mail and slack. But, we should install guzzlehttp/guzzle for slack. By default, we get mails for every actions. If you are want to know more about sending notifiations in laravel, you can read this article title “” which explains pretty well about notification.

If you want to dig in more detail about the notification classes, follow the below code in backup.php.

//config/backup.php

/*
 * You can get notified when specific events occur. Out of the box, you can use 'mail' and 'slack'.
 * For Slack you need to install guzzlehttp/guzzle.
 *
 * You can also use your own notification classes, just make sure the class is named after one of
 * the `Spatie\Backup\Events` classes.
 */
'notifications' => [

    'notifications' => [
        \Spatie\Backup\Notifications\Notifications\BackupHasFailed::class         => ['mail'],
        \Spatie\Backup\Notifications\Notifications\UnhealthyBackupWasFound::class => ['mail'],
        \Spatie\Backup\Notifications\Notifications\CleanupHasFailed::class        => ['mail'],
        \Spatie\Backup\Notifications\Notifications\BackupWasSuccessful::class     => ['mail'],
        \Spatie\Backup\Notifications\Notifications\HealthyBackupWasFound::class   => ['mail'],
        \Spatie\Backup\Notifications\Notifications\CleanupWasSuccessful::class    => ['mail'],
    ],

    /*
     * Here you can specify the notifiable to which the notifications should be sent. The default
     * notifiable will use the variables specified in this config file.
     */
    'notifiable' => \Spatie\Backup\Notifications\Notifiable::class,

    'mail' => [
        'to' => 'your@email.com',
    ],

    'slack' => [
        'webhook_url' => '',
    ],
],

Below is a screenshot of emails sent during the execution of backup commands.
How to backup your laravel app and database - kodementor

Conslusion

Please note that, backing up the application files back up all your files including configurations and other sensitive credentials. So, be sure to make the file secure on the server. These are some of the main functionalities of laravel-backup package But you can dig in more details about other features as well in the official documentation.

LEAVE A REPLY

Please enter your comment!
Please enter your name here