Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

A modern backup solution for Laravel apps

Original – by Freek Van der Herten – 9 minute read

Today our team released a new major version of laravel-backup. It can backup the files and databases of your application to one or more external filesystems. It uses Laravel's native cloud filesystem to do this. The package can also notify you via Slack and/or email when something goes wrong with your backups. We've also created a dedicated site with full documentation. In this blogpost we want to give you some background of why and how the package was created.

History

In the Laravel 4 days we ware using Johannes Schickling's backup package to dump an application's database and copy it over to S3. Then Laravel 5 came out. Unfortunately Johannes' package was never updated. So... we had to create a backup package ourselves. Version 1 could simply dump the database. The next major version added functionality to zip specific directories and copy them over to external filesystems.

A lot of other developers found laravel-backup useful. A few weeks ago the package reached 40k downloads and 500 stars on GitHub. We thought this was amazing. It's our most popular package by far. Creating a popular package was such an awesome experience that our team is now continuously releasing new open source stuff and helping the community.

In January of this year Jack Fruh of the Laravel News Podcast called to talk about the backup backage. You can listen to our conversation in episode 8 of the podcast. At a certain point Jack asks if the package sends out notifications when something goes wrong (it didn't). That question led us to add monitoring functionality and notifications to version 3. Thanks Jack!

The package was one of the first Spatie packages that was ever released. In the past year we learned a lot, so we definitely could see room for improvement in the old code.

An overview of all functionality in version 3

Version 3 of the package has plenty awesome features. Take a look at the config file to get a quick overview of all functionality. Most options are self-explanatory, but there some comments to make everything very clear.

Taking backups

Most importantly, the package can take backups. That's probably a good thing considering the package is named laravel-backup. A backup is a zip file that contains the files of your application together with the dumps of one or more databases. The zipfile can be copied over to one or more filesystems.

To take a backup you can run this command: php artisan backup:run. We recommend that you schedule this command using Laravel's native scheduler. To take a quick backup of your database you can run php artisan backup:run --only-db. This can be handy in your deployment strategy.

Cleaning up old backups

Over time the amount of backups and the storage needed to keep them will grow. At some point you are going to want to clean up old backups. The package provides an opinionated method to determine which old backups should be deleted. This is how the clean up works:
  • Rule #1: it will never delete the youngest backup regardless of it's size or age
  • Rule #2: it will keep all backups for the amount of days specified in `keepAllBackupsForDays`
  • Rule #3: it'll only keep daily backups for the amount of days specified in `keepDailyBackupsForDays` for all backups older than those that rule #2 takes care of
  • Rule #4: it'll only keep weekly backups for the amount of days specified in `keepMonthlyBackupsForMonths` for all backups older than those that rule #3 takes care of
  • Rule #5: it'll only keep yearly backups for the amount of years specified in `keepYearlyBackupsForYears` for all backups older than those that rule #4 takes care of
  • Rule #6: it will delete backups will keep on deleting backups until the used storage is lower than the number specified in `deleteOldestBackupsWhenUsingMoreMegabytesThan`.
Of course the numbers used in the default configuration can be adjusted to your own liking. This strategy ensures that you have a lot of young backups and a few older ones.

To clean up all backups simply run php artisan backup:clean. We recommend to schedule this command as well.

Monitoring the health of all backups

The package can monitor the health of every application it is installed into. If a backup is unhealty, a notification can be sent to you via mail of Slack, more on that later.

To monitor the backups of your applications we recommend setting up this package in a separate Laravel installation preferably on a separate server. Doing it this way will ensure that the monitoring will still work even if one of the applications you are monitoring is broken.

To get a quick overview of the health all your backups you can run php artisan backup:list. The output of that command will look like this:

output of backup:list

In the screenshot above you see a quick test I whipped up that uses a well configured local destination and S3 destination with some faulty credentials.

Sending notifications

The package can let you know that your backups are (not) ok. It can notify you via mail and or Slack when an (un)healthy backup is found or when a backup or clean was (un)successful.

This is what a Slack notification looks like: unhealthbackup

Some other tidbits

Besides all that functionality, there are lots of other tiny features that you can make use of:

Show me the code!

We made great efforts to create readable code. Take a look at this function from the `BackupJob`-class which takes care of creating backups: ```php public function run() { try { $this->temporaryDirectory = TemporaryDirectory::create();
    $zip = $this->createZipContainingAllFilesToBeBackedUp();

    $this->copyToBackupDestinations($zip);

    $this->temporaryDirectory->delete();

} catch (Exception $exception) {
    event(new BackupHasFailed($exception));
}

}



This is the code that creates the zip-file:
```php
protected function createZipContainingAllFilesToBeBackedUp()
{
    $zip = Zip::create($this->temporaryDirectory->getPath(date('Y-m-d-His').'.zip'));

    $this->addDatabaseDumpsToZip($zip);

    $this->addSelectedFilesToZip($zip);

    event(new BackupZipWasCreated($zip));

    return $zip;
}

By browsing the code you can easily work out the inner workings of the package. Reading other people's code is always a good way to learn new stuff. We hope you pick up a few things by reading ours.

The documentation site

The previous version of the backup had, like most packages, a simple readme on GitHub to guide users. A simple readme wasn't going to cut it anymore. That's why we created a small documentation site.

It's built with Laravel 5.2. The source code of the entire application is available on GitHub. If you have an idea to improve the docs or see an error, submit a PR to that repo. Changes to the repo are auto deployed to a DigitalOcean droplet that runs the documentation site.

The views of the application are not simple blade views, but Markdown files. All requests are routed to the PageController which is responsible for converting the markdown file to html and displaying it.

The markdown is parsed by the League's CommonMark package in combination with our own yaml-front-matter parser. The menu of the site is rendered by a new package called laravel-menu, of which we will release a stable first release soon. It'll feature a very easy to use syntax and a handy way to mark menu items as being active.

On the usage of PHP 5

Some of you might already know that we decided to, from this point on, only release PHP 7 packages. One of our arguments to go PHP 7 only was that we primarily create packages for our own projects and don't really care if a package is popular or not (though on a personal level having a package becoming popular feels awesome). When we started out coding up the new version of laravel-backup the package was PHP 7 only.

But then DigitalOcean lost one of our servers. From one moment to the next it ceased to exist. Poof! This event changed our stance. We decided that the backup package should be available for as many people as possible. That's why we ensured that package is compatible with PHP 5. We do foresee however that, by the end of this year, we'll release a PHP 7 only version.

Alternatives

We see our package as a good solution for small to medium sized projects. But of course there are plenty of quality alternatives.

Backup Manager, by Mitchell van Wijngaarden and Shawn McCool, is a framework agnostic solution. It can backup and restore files and databases to a myriad of filesystems.

BackupPC is an enterprise grade backup system. It works by SSH'ing into your servers and rsync'ing all files to it's own disk. It's a little bit harder to configure, you'll find installation instructions on the DigitalOcean site. Another enterprise grade solution is Bakula.

If you're in the market for a SaaS solution, take a look at Ottomatik.io. This service isn't free, but in exchange for your hard earner dollars or euros you get a very good-looking UI to configure backups and restores.

Closing notes

You've almost reached the end of this post. If you made it this far we hope you'll try out the package and let us know what you think of it.

It's been fun creating v3. Hopefully it'll become as successful as the previous version. Creating this package is a good reminder that the biggest effort in creating a package doesn't lie in creating working code, but refactoring it for maximum readability, creating tests, writing and layouting documentation and... this introductory blog post. Probably we'll have to spend some time answering questions and fixing issues. But that's all worth it.

We'll leave you with two links:

Do you like the this package? Or have a suggestion on how to make it better? Let me know in the comments below.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "A modern backup solution for Laravel apps"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.