Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Laravel Spatie backup with controller routes and views
namespace App\Http\Controllers;
use Alert;
use Artisan;
use Carbon\Carbon;
use Log;
use Spatie\Backup\Helpers\Format;
use Storage;
class BackupController extends Controller
public function __construct()
public function index()
$disk = Storage::disk(config('backup.backup.destination.disks')[0]);
$files = $disk->files(config(''));
$backups = [];
// make an array of backup files, with their filesize and creation date
foreach ($files as $k => $f) {
// only take the zip files into account
if (substr($f, -4) == '.zip' && $disk->exists($f)) {
$backups[] = [
'file_path' => $f,
'file_name' => str_replace(config('') . '/', '', $f),
'file_size' => Format::humanReadableSize($disk->size($f)),
'last_modified' => Carbon::createFromTimestamp($disk->lastModified($f)),
// reverse the backups, so the newest one would be on top
$backups = array_reverse($backups);
return view("admin.backups")->with(compact('backups'));
public function create()
try {
// start the backup process
Artisan::call('backup:run', ['--only-db' => 'true']);
$output = Artisan::output();
// log the results
Log::info("Backpack\BackupManager -- new backup started from admin interface \r\n" . $output);
// return the results as a response to the ajax call
Alert::success('New backup created');
return redirect()->back();
} catch (Exception $e) {
return redirect()->back();
* Downloads a backup zip file.
* TODO: make it work no matter the flysystem driver (S3 Bucket, etc).
public function download($file_name)
$file = config('') . '/' . $file_name;
$disk = Storage::disk(config('backup.backup.destination.disks')[0]);
if ($disk->exists($file)) {
$fs = Storage::disk(config('backup.backup.destination.disks')[0])->getDriver();
$stream = $fs->readStream($file);
return \Response::stream(function () use ($stream) {
}, 200, [
"Content-Type" => $fs->getMimetype($file),
"Content-Length" => $fs->getSize($file),
"Content-disposition" => "attachment; filename=\"" . basename($file) . "\"",
} else {
abort(404, "The backup file doesn't exist.");
* Deletes a backup file.
public function delete($file_name)
$disk = Storage::disk(config('backup.backup.destination.disks')[0]);
if ($disk->exists(config('') . '/' . $file_name)) {
$disk->delete(config('') . '/' . $file_name);
return redirect()->back();
} else {
abort(404, "The backup file doesn't exist.");
@if (count($backups))
<table class="table table-striped table-bordered">
<thead class="thead-dark">
@foreach($backups as $backup)
<td>{{ $backup['file_name'] }}</td>
<td>{{ $backup['file_size'] }}</td>
{{ date('d/M/Y, g:ia', strtotime($backup['last_modified'])) }}
{{ diff_date_for_humans($backup['last_modified']) }}
<td class="text-right">
<a class="btn btn-primary" href="{{ url('backup/download/'.$backup['file_name']) }}">
<i class="fas fa-cloud-download"></i> Download</a>
<a class="btn btn-xs btn-danger" data-button-type="delete" href="{{ url('backup/delete/'.$backup['file_name']) }}">
<i class="fal fa-trash"></i>
<div class="text-center py-5">
<h1 class="text-muted">No existen backups</h1>
<div class="container -body-block pb-5">
@card(['title' => 'Backups de la base de datos'])
<li class="nav-item active mr-3">
<a href="{{ url('backup/create') }}" class="nav-link text-primary" title="Crear nuevo backup">
<i class="far fa-plus" aria-hidden="true"></i> Crear nuevo backup
<div class="py-4"></div>
<div class="py-3"></div>
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">{{$title}}</div>
<div class="card-body">
{{ $slot }}
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('', '') }}</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
window.AppRootData = {!! json_encode([
'csrfToken' => csrf_token(),
'state' => ['user' => Auth::user()]
]) !!};
<div id="app" class="boxx-wrapper">
<div class="album py-5 bg-light">
<!-- Scripts -->
@if (app()->isLocal())
<script src="{{ mix('js/app.js') }}"></script>
<script src="{{ mix('js/manifest.js') }}"></script>
<script src="{{ mix('js/vendor.js') }}"></script>
<script src="{{ mix('js/app.js') }}"></script>
use Carbon\Carbon;
function diff_date_for_humans(Carbon $date) : string
return (new Jenssegers\Date\Date($date->timestamp))->ago();
function diff_string_for_humans($stringDate) : string
$date = Jenssegers\Date\Date::createFromFormat('Y-m-d H:i:s', $stringDate);
return (new Jenssegers\Date\Date($date))->ago();
function scannerTableLabel($stringDate) : string
$now = Jenssegers\Date\Date::now();
$date = Jenssegers\Date\Date::createFromFormat('Y-m-d H:i:s', $stringDate);
$printDate = (new Jenssegers\Date\Date($date))->ago();
$color = $now > $date ? 'info' : 'danger';
$res = '<span class="badge badge-'.$color.'" style="color:white;">SCANNER: ';
$res .= $printDate ;
$res .= '</span>';
return $res;
<nav class="navbar navbar-expand-md navbar-light bg-light">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#table-actions-nav-menu" aria-controls="table-actions-nav-menu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
<div class="collapse navbar-collapse" id="table-actions-nav-menu">
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
{{ $slot }}
Route::get('backup', 'BackupController@index');
Route::get('backup/create', 'BackupController@create');
Route::get('backup/download/{file_name}', 'BackupController@download');
Route::get('backup/delete/{file_name}', 'BackupController@delete');

This comment has been minimized.

Copy link
Owner Author

@kikoseijo kikoseijo commented Feb 22, 2018

No está al completo, pero le falta lo mínimo.


Special thanks to supporters and clients that provide me with enough time to work on contributing to develop this packages for the WWW.

DevOps Web development
AppDev Mobile aplications
SocialApp Residents mobile application Freelance senior programmer

Created by Kiko Seijo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment