Installing Laravel-backup
For this activity I’m going to be using the Laravel-Backup tool from Spatie
https://github.com/spatie/laravel-backup
Follow the instructions on the github readme.
- composer require spatie/laravel-backup
- add service provider to app.php Spatie\Backup\BackupServiceProvider::class,
- publish the config file. This adds a new laravel-backup config item to the config folder
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"
To start with, we will test the backup using the local file system, as comes enabled by default.
You now have a couple of additional functions in Artisan
Try php artisan backup:run
If it returns an error then it’s probably because your system cannot find the needed mysqldump command. If this is not found then you will have to track it down on your machine and then adjust the myqsl dump_command_path in the laravel-backup.php file. Make sure the path ends in a forward slash as the mysqldump command will be appended to it.
'mysql' => [ /* * The path to the mysqldump binary. You can leave this empty * if the binary is installed in the default location. */ 'dump_command_path' => '/Applications/MAMP/Library/bin/',
When using the default Local storage, the backup will be in the storage/app/backups folder. At this point, you should test the backup files
Configuring S3 to receive the files
Assuming that you have an AWS S3 account with Amazon.
First of all create the bucket that will be used. I recommend a separate bucket for each site since that allows you to secure them individually.
Next, create an IAM identity for the bucket. Identity and Access Management is an identity management solution and will prevent the credentials stored on this website from accessing other backups. The last thing you want is an intruder on one site accessing the backups for other sites since these backups will contain access credentials for those other sites.
- Select create user
- Enter a name for the user (the name of the site perhaps)
- Copy the access credentials. These will be used to configure Laravel Flysystem in a moment.
Select the User and click Permissions then Inline Policies
Select Create One, then Custom Policy
Provide a policy name (no spaces)
Add the policy as below, adding the name of your new bucket
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "*", "Resource": [ "arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*" ], "Condition": {} } ] }
Configure Laravel Flysystem
Edit config/filesystems.php
Under disks->s3, change the following so that the S3 keys can be picked up from .env and not end up in your repo.
'driver' => 's3', 'key' => env('S3_KEY'), 'secret' => env('S3_SECRET'), 'region' => env('S3_REGION'), 'bucket' => env('S3_BUCKET'),
Then set the .env file with the actual values
S3_KEY='AKI****F2CH4****PFKQ' #your access key S3_SECRET='kEjL********r3r+4QjkbU********NQIiiEfhb' #secret access key S3_REGION='eu-west-1' S3_BUCKET='your-bucket-name'
Next tell laravel-backup to use S3 (config/laravel-backup.php)
/* * The filesystem(s) you on which the backups will be stored. Choose one or more * of the filesystems you configured in app/config/filesystems.php */ 'filesystem' => ['s3'],
and set the folder in which to store the backup
/* * The path where the backups will be saved. This path * is relative to the root you configured on your chosen * filesystem(s). * * If you're using the local filesystem a .gitignore file will * be automatically placed in this directory so you don't * accidentally end up committing these backups. */ 'path' => 'backup',
Install S3 library
The S3 libraries are not shipped by default so you will need to add these via composer
composer require league/flysystem-aws-s3-v3 ~1.0
Test so far…
You should run the backup again and hopefully your files will be pushed to S3, which you can inspect through the S3 file browser
Configuring CRON to run the job
Configure the server to call the Schedule:run artisan command every minute. This is covered in the Laravel docs.
If your host does not support CRON, then A suggestion is made in an earlier blog post.
Setup entries in your Http/kernel.php file;
protected function schedule(Schedule $schedule) { $schedule->command('backup:run',['--only-files' => '','--suffix' => '_files']) ->weekly()->mondays()->at('03:00') ->description('My-project Files backup') ->sendOutputTo('storage/logs/backup.log') ->emailOutputTo('mark@novate.co.uk') ->before(function(){ Log::info('Commencing Files Backup'); }) ->after(function(){ Log::info('My-project Files backup complete'); }); $schedule->command('backup:run',['--only-db' => '','--suffix' => '_db']) ->twiceDaily(2,14) ->description('My-project Database backup') ->sendOutputTo('storage/logs/backup.log') ->emailOutputTo('mark@novate.co.uk') ->before(function(){ Log::info('Commencing Database backup'); }) ->after(function(){ Log::info('My-project Database backup complete'); }); }
So here, I have two backup jobs, one running once per week for all the files, and then a twice-daily database backup. Following each, the log of the backup is sent via email.
Summary
This has been a long-winded setup as there are multiple steps. Laravel-backup is a very flexible backup solution and leverages league\flysystem to store backups to the cloud.
Using Amazon S3 and protecting it with IAM provides a robust destination for your backups.
Hi,
While doing mysql back, the mysqldump command trying to use root user instead of user specified in config file. Any idea.
mysqldump is probably being run via exec (ie, from the command line). You could try posting a question for Freek on github to see of the user name could be passed to the dump command?