PHPackages                             wnx/laravel-backup-restore - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. wnx/laravel-backup-restore

ActiveLibrary[Database &amp; ORM](/categories/database)

wnx/laravel-backup-restore
==========================

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

v1.9.2(2mo ago)203330.1k↑24.6%20[2 issues](https://github.com/stefanzweifel/laravel-backup-restore/issues)1MITPHPPHP ^8.4CI passing

Since Mar 21Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/stefanzweifel/laravel-backup-restore)[ Packagist](https://packagist.org/packages/wnx/laravel-backup-restore)[ Docs](https://github.com/stefanzweifel/laravel-backup-restore)[ Fund](https://buymeacoff.ee/3oQ64YW)[ GitHub Sponsors](https://github.com/stefanzweifel)[ RSS](/packages/wnx-laravel-backup-restore/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (24)Versions (35)Used By (1)

Restore database backups made with spatie/laravel-backup
========================================================

[](#restore-database-backups-made-with-spatielaravel-backup)

[![Latest Version on Packagist](https://camo.githubusercontent.com/5cae969e7ca19af5f940fb6f87af4abd6082234725f5f0cdce524ca57b450ac1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f776e782f6c61726176656c2d6261636b75702d726573746f72652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wnx/laravel-backup-restore)[![GitHub Tests Action Status](https://camo.githubusercontent.com/c987ac7630ed4fadc293f60c1c75ac89a76947af9e484344d1be693848e25e7d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f73746566616e7a77656966656c2f6c61726176656c2d6261636b75702d726573746f72652f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/stefanzweifel/laravel-backup-restore/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/a8c717186f66eccd0eac82f72202fe9c30f72bdb1bcc5a8257f8a1f4e0db3348/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f73746566616e7a77656966656c2f6c61726176656c2d6261636b75702d726573746f72652f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/stefanzweifel/laravel-backup-restore/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/65752fab8f63c9f1ae13c7f48afa57917071a9e423f867ea5d7ba3332cb879d9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f776e782f6c61726176656c2d6261636b75702d726573746f72652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wnx/laravel-backup-restore)

A package to restore a database backup created by the [spatie/laravel-backup](https://github.com/spatie/laravel-backup) package.

The package requires Laravel v12 or higher and PHP 8.4 or higher.

Installation
------------

[](#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"
```

These are 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
-----

[](#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

[](#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
    --keep
```

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

#### `--disk`

[](#--disk)

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

#### `--backup`

[](#--backup)

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

#### `--connection`

[](#--connection)

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

#### `--password`

[](#--password)

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

#### `--reset`

[](#--reset)

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

#### `--keep`

[](#--keep)

Keeps the downloaded backup (and the decrypted backup folder) in existence. You need to delete it by hand. Useful for extracting and restoring backuped files. 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

[](#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,
    ],
```

Limitations
-----------

[](#limitations)

- The package only supports backups created by the [spatie/laravel-backup](https://github.com/spatie/laravel-backup) package.
- The package does not support restoring files from backups.
- The package does not support restoring backups from or in a multi-tenant environment.

Troubleshooting
---------------

[](#troubleshooting)

### Failed to restore Backup: @@GLOBAL.GTID\_PURGED cannot be changed

[](#failed-to-restore-backup-globalgtid_purged-cannot-be-changed)

If your MySQL backup was created on a DigitalOcean managed database, you might encounter the following error when restoring the backup:

> ERROR 3546 (HY000) at line 14: @@GLOBAL.GTID\_PURGED cannot be changed: the added gtid set must not overlap with @@GLOBAL.GTID\_EXECUTED

This is caused by DigitalOcean's MySQL settings that enable [GTID](https://dev.mysql.com/doc/refman/8.4/en/replication-gtids-concepts.html) on their managed databases.

You can disable GTID when creating the MySQL backup by adding the following option to the `dump`-section of your database connection in `config/backup.php`-file:

```
'dump' => [
    'add_extra_option' => '--set-gtid-purged=OFF --skip-disable-keys',
],
```

If your backup was created with GTID enabled, the package currently can't restore it.
See [Issue 93](https://github.com/stefanzweifel/laravel-backup-restore/issues/93) for details.

Check Backup Integrity automatically with GitHub Actions
--------------------------------------------------------

[](#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](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch)) or runs automatically on a schedule ([`schedule`-trigger](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule)). 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](https://docs.github.com/en/actions/security-guides/encrypted-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
-------

[](#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](https://github.com/stefanzweifel/laravel-backup-restore/blob/main/tests/TestCase.php) for details.

### Testing with Testbench

[](#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
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Stefan Zweifel](https://github.com/stefanzweifel)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

63

—

FairBetter than 99% of packages

Maintenance84

Actively maintained with recent releases

Popularity54

Moderate usage in the ecosystem

Community24

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 80.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~35 days

Recently: every ~43 days

Total

31

Last Release

80d ago

Major Versions

v0.3.1 → v1.0.02023-05-29

PHP version history (3 changes)v0.1.0PHP ^8.1

v1.4.0PHP ^8.2

v1.8.0PHP ^8.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/b6e76cb0a5ed6788731857a8b4e1a27e283cef831fe42bf9636549bf9b35ddd7?d=identicon)[stefanzweifel](/maintainers/stefanzweifel)

---

Top Contributors

[![stefanzweifel](https://avatars.githubusercontent.com/u/1080923?v=4)](https://github.com/stefanzweifel "stefanzweifel (106 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (19 commits)")[![alies-dev](https://avatars.githubusercontent.com/u/5278175?v=4)](https://github.com/alies-dev "alies-dev (2 commits)")[![ojsoft](https://avatars.githubusercontent.com/u/21057323?v=4)](https://github.com/ojsoft "ojsoft (1 commits)")[![pieterclaerhout](https://avatars.githubusercontent.com/u/74731?v=4)](https://github.com/pieterclaerhout "pieterclaerhout (1 commits)")[![upsite4k](https://avatars.githubusercontent.com/u/28684500?v=4)](https://github.com/upsite4k "upsite4k (1 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")[![Human018](https://avatars.githubusercontent.com/u/8413094?v=4)](https://github.com/Human018 "Human018 (1 commits)")

---

Tags

backuplaravelrestorespatie-laravel-backuplaravellaravel-backuplaravel-backup-restore

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/wnx-laravel-backup-restore/health.svg)

```
[![Health](https://phpackages.com/badges/wnx-laravel-backup-restore/health.svg)](https://phpackages.com/packages/wnx-laravel-backup-restore)
```

###  Alternatives

[spatie/laravel-backup

A Laravel package to backup your application

6.0k21.8M191](/packages/spatie-laravel-backup)[spatie/laravel-health

Monitor the health of a Laravel application

85810.0M83](/packages/spatie-laravel-health)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)[spatie/laravel-model-flags

Add flags to Eloquent models

4301.1M1](/packages/spatie-laravel-model-flags)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)[spatie/laravel-sql-commenter

Add comments to SQL queries made by Laravel

1931.4M1](/packages/spatie-laravel-sql-commenter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
