• Stars
    star
    162
  • Rank 232,284 (Top 5 %)
  • Language
    PHP
  • License
    MIT License
  • Created almost 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A package to restore database backups made with spatie/laravel-backup.

Restore database backups made with spatie/laravel-backup

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A package to restore a database backup created by the spatie/laravel-backup package.

The package requires Laravel v10.17 or higher and PHP 8.1 or higher.

Installation

You can install the package via composer:

composer require wnx/laravel-backup-restore

Optionally, you can publish the config file with:

php artisan vendor:publish --tag="backup-restore-config"

This is the contents of the published config file:

return [

    /**
     * Health checks are run after a given backup has been restored.
     * With health checks, you can make sure that the restored database contains the data you expect.
     * By default, we check if the restored database contains any tables.
     *
     * You can add your own health checks by adding a class that extends the HealthCheck class.
     * The restore command will fail, if any health checks fail.
     */
    'health-checks' => [
        \Wnx\LaravelBackupRestore\HealthChecks\Checks\DatabaseHasTables::class,
    ],
];

Usage

To restore a backup, run the following command.

php artisan backup:restore

You will be prompted to select the backup you want to restore and whether the encryption password from the configuration should be used, to decrypt the backup.

The package relies on an existing config/backup.php-file to find your backups, encryption/decryption key and database connections.

Note
By default, the name of a backup equals the value of the APP_NAME-env variable. The restore-commands looks for backups in a folder with that backup name. Make sure that the APP_NAME-value is correct in the environment you're running the command.

Optional Command Options

You can pass disk, backup, database connection and decryption password to the Artisan command directly, to speed things up.

php artisan backup:restore
    --disk=s3
    --backup=latest 
    --connection=mysql 
    --password=my-secret-password 
    --reset

Note that we used latest as the value for --backup. The command will automatically download the latest available backup and restore its database.

--disk

The filesystem disk to look for backups. Defaults to the first destination disk configured in config/backup.php.

--backup

Relative path to the backup file that should be restored. Use latest to automatically select latest backup.

--connection

Database connection to restore backup. Defaults to the first source database connection configured in config/backup.php.

--password

Password used to decrypt a possible encrypted backup. Defaults to encryption password set in config/backup.php.

--reset

Reset the database before restoring the backup. Defaults to false.


The command asks for confirmation before starting the restore process. If you run the backup:restore-command in an environment where you can't confirm the process (for example through a cronjob), you can use the --no-interaction-option to bypass the question.

php artisan backup:restore
    --disk=s3
    --backup=latest 
    --connection=mysql 
    --password=my-secret-password 
    --reset
    --no-interaction

Health Checks

After the backup has been restored, the package will run a series of health checks to ensure that the database has been imported correctly. By default, the package will check if the database has tables after the restore.

You can add your own health checks by creating classes that extend Wnx\LaravelBackupRestore\HealthChecks\HealthCheck-class.

namespace App\HealthChecks;

use Wnx\LaravelBackupRestore\PendingRestore;
use Wnx\LaravelBackupRestore\HealthChecks\HealthCheck;

class MyCustomHealthCheck extends HealthCheck
{
    public function run(PendingRestore $pendingRestore): Result
    {
        $result = Result::make($this);

        // We assume that your app generates sales every day.
        // This check ensures that the database contains sales from yesterday.
        $newSales = \App\Models\Sale::query()
            ->whereBetween('created_at', [
                now()->subDay()->startOfDay(), 
                now()->subDay()->endOfDay()
            ])
            ->exists();

        // If no sales were created yesterday, we consider the restore as failed.
        if ($newSales === false) {
            return $result->failed('Database contains no sales from yesterday.');
        }

        return $result->ok();
    }
}

Add your health check to the health-checks-array in the config/laravel-backup-restore.php-file.

    'health-checks' => [
        \Wnx\LaravelBackupRestore\HealthChecks\Checks\DatabaseHasTables::class,
        \App\HealthChecks\MyCustomHealthCheck::class,
    ],

Check Backup Integrity automatically with GitHub Actions

In addition to running the backup:restore command manually, you can also use this package to regularly test the integrity of your backups using GitHub Actions.

The GitHub Actions workflow below can either be triggered manually through the Github UI (workflow_dispatch-trigger) or runs automatically on a schedule (schedule-trigger). The workflow starts an empty MySQL database, clones your Laravel application, sets up PHP, installs composer dependencies and sets up the Laravel app. It then downloads, decrypts and restores the latest available backup to the MySQL database available in the GitHub Actions workflow run. The database is wiped, before the workflow completes.

Note that we pass a couple of env variables to the backup:restore command. Most of those values have been declared as GitHub Action secrets. By using secrets our AWS keys are not being leaked in the workflow logs.

If the restore command fails, the entire workflow will fail, you and will receive a notification from GitHub. This is obviously just a starting point. You can add more steps to the workflow, to – for example – notify you through Slack, if a restore succeeded or failed.

name: Validate Backup Integrity

on:
  # Allow triggering this workflow manually through the GitHub UI.
  workflow_dispatch:
  schedule:
    # Run workflow automatically on the first day of each month at 14:00 UTC
    # https://crontab.guru/#0_14_1_*_*
    - cron: "0 14 1 * *"

jobs:
  restore-backup:
    name: Restore backup
    runs-on: ubuntu-latest

    services:
      # Start MySQL and create an empty "laravel"-database
      mysql:
        image: mysql:latest
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: laravel
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.2

      - uses: ramsey/composer-install@v2

      - run: cp .env.example .env

      - run: php artisan key:generate

      # Download latest backup and restore it to the "laravel"-database.
      # By default the command checks, if the database contains any tables after the restore. 
      # You can write your own Health Checks to extend this feature.
      - name: Restore Backup
        run: php artisan backup:restore --backup=latest --no-interaction
        env:
            APP_NAME: 'Laravel'
            DB_PASSWORD: 'password'
            AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
            AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
            AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
            AWS_BACKUP_BUCKET: ${{ secrets.AWS_BACKUP_BUCKET }}
            BACKUP_ARCHIVE_PASSWORD: ${{ secrets.BACKUP_ARCHIVE_PASSWORD }}

      # Wipe database after the backup has been restored.
      - name: Wipe Database
        run: php artisan db:wipe --no-interaction
        env:
            DB_PASSWORD: 'password'

Testing

The package comes with an extensive test suite. To run it, you need MySQL, PostgreSQL and sqlite installed on your system.

composer test

For MySQL and PostgreSQL the package expects that a laravel_backup_restore database exists and is accessible to a root-user without using a password.

You can change user, password and database by passing ENV-variables to the shell command tp run the tests … or change the settings locally to your needs. See TestCase for details.

Testing with Testbench

You can invoke the backup:restore command using testbench to test the command like you would in a Laravel application.

vendor/bin/testbench backup:restore --disk=remote

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

More Repositories

1

git-auto-commit-action

Automatically commit and push changed files back to GitHub with this GitHub Action for the 80% use case.
Shell
1,970
star
2

laravel-stats

📈 Get insights about your Laravel or Lumen Project
PHP
1,707
star
3

screeenly

📸 Screenshot as a Service
PHP
493
star
4

sidecar-browsershot

A Sidecar function to run Browsershot on Lambda.
PHP
195
star
5

laravel-sends

A package to keep track of outgoing emails in your Laravel application.
PHP
175
star
6

changelog-updater-action

A GitHub Action to automatically update a "Keep a Changelog" CHANGELOG with the latest release notes.
Shell
122
star
7

diary-app

🔐An End-To-End Encrypted Diary Web App
PHP
93
star
8

laravel-github-actions-demo

A demo application to showcase useful GitHub Actions for PHP developers
PHP
30
star
9

kirby-json-feed

Kirby Plugin to serve a JSON Feed
PHP
26
star
10

reusable-workflows

A collection of reusable GitHub Actions workflows I use in my public and private projects.
26
star
11

dotfiles

🐼 My dotfiles
Shell
23
star
12

imgubox

[Deprecated] Store Imgur favorites in Dropbox
PHP
22
star
13

php-changelog-updater

PHP CLI to add latest release notes to a CHANGELOG
PHP
22
star
14

ScreeenlyClient

PHP API Wrapper for Screeenly
PHP
22
star
15

laravel-phpinsights-action

Run PHP Insights in Laravel in Github Actions
Dockerfile
21
star
16

php-swiss-cantons

🇨🇭 Find Swiss Canton by abbreviation, name or zipcode.
PHP
17
star
17

alfred-emoji-pack

PHP Script to generate Snippets for Alfred with all available Emojis.
PHP
14
star
18

commonmark-mark-extension

Render ==highlighted== texts as <mark> elements in league/commonmark
PHP
13
star
19

mp3-to-m4r-converter

Bulk-convert mp3 to m4r-files
Shell
13
star
20

deployer-on-github-actions-example

Example Repository showcasing how to run deployer on GitHub Actions
PHP
13
star
21

laravel-file-encryption-example

Example project to showcase backend file encryption
PHP
12
star
22

laravel-download-statistics-app

Aggregated download statistics for Laravel.
PHP
12
star
23

phpinsights-action

Run PHP Insights in Github Actions
Dockerfile
11
star
24

dropshare-landingpage

A minimal landingpage for Dropshare.app
HTML
7
star
25

uberspaceScripts

My personal collection of useful scripts, when hosting on uberspace.de
Shell
7
star
26

esbuild-mix-manifest-plugin

esbuild plugin to generate mix-manifest.json file compatible with Laravel Mix.
TypeScript
7
star
27

commonmark-markdown-renderer

Render a league/commonmark AST back to Markdown.
PHP
6
star
28

dirby

An opinionated Kirby theme for documentations
CSS
6
star
29

laravel-encryption-key-generator

A simple app to generate new Laravel encryption keys for you.
PHP
6
star
30

vue-tailwind-css-modules-demo

Demo application highlighting the use of Tailwind CSS in Vue Components
JavaScript
6
star
31

dropshare-tailwind-landingpage

Simple landingpage to use with Dropshare
JavaScript
5
star
32

js-swiss-cantons

🇨🇭 Find Swiss Canton by abbreviation or name
JavaScript
5
star
33

getting-started-with-bash-testing

Example Bash Project to get started with testing with Bats.
Shell
5
star
34

kirby-laravel-mix-helper

Helper to use Version Busting of Laravel Mix
PHP
5
star
35

icq-christmas-card

Revive one of the old ICQ Christmas Cards from 2002.
HTML
4
star
36

multi-photo-crop

🏙 A tool to crop and split photos from a single image
PHP
4
star
37

swiss-canton-iconfont

Serve the 26 Swiss Cantons in a simple icon font
CSS
3
star
38

example-advanced-eloquent-with-pivot

Example project mentioned in an article of mine.
PHP
3
star
39

asana-expander-extension

Browser Extension to automatically expand long comments in Asana
TypeScript
3
star
40

photon-the-archive-theme

A "The Archive" theme based on the PHPStorm Theme "Photon" by Brent Roose
3
star
41

alfred-emoji-pack-node

Emojis at your fingertips as Alfred Snippets
JavaScript
2
star
42

radio-srf-menubarapp

📻 A simple menubar application to play Radio SRF stations
Swift
2
star
43

faker-swiss-locations

Provider to generate valid Swiss location data for Faker PHP.
PHP
2
star
44

php-search-string-parser

[In Development] Use Search Input Strings similar to Github
PHP
2
star
45

git-auto-commit-action-demo-app

A demo application to test git-auto-commit Github Action
PHP
2
star
46

oh-dear-request-run-action

Trigger Oh Dear runs through GitHub Actions.
2
star
47

life-expectancy-visualisation

A small application to visualise the life expectancy of different people around the world.
TypeScript
2
star
48

scratchpad

Minimal Scratchpad
HTML
1
star
49

stefanzweifel

1
star
50

chrome-facebook-to-wikipedia-redirect

Read a Wikipedia Article instead of your Newsfeed
JavaScript
1
star
51

user-agent-analyzer

User Agent analysis as a Service.
PHP
1
star
52

git-auto-commit-demo-app

A demo application to test the git-auto-commit Action.
1
star
53

sidecar-browsershot-layer

AWS Lambda Layer containing puppeteer-core. Used by sidecar-browsershot
Shell
1
star