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:
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:
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.
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.