spatie/laravel-backup 사용 예

54143 단어 Laraveltech
https://github.com/spatie/laravel-backup
dependency
https://github.com/spatie/db-dumper

laravel-backup


프로비저닝


vendor/spatie/laravel-backup/src
├── BackupDestination
│   ├── Backup.php
│   ├── BackupCollection.php
│   ├── BackupDestination.php
│   └── BackupDestinationFactory.php
├── BackupServiceProvider.php
├── Commands
│   ├── BackupCommand.php
│   ├── BaseCommand.php
│   ├── CleanupCommand.php
│   ├── ListCommand.php
│   └── MonitorCommand.php
├── Events
│   ├── BackupHasFailed.php
│   ├── BackupManifestWasCreated.php
│   ├── BackupWasSuccessful.php
│   ├── BackupZipWasCreated.php
│   ├── CleanupHasFailed.php
│   ├── CleanupWasSuccessful.php
│   ├── HealthyBackupWasFound.php
│   └── UnhealthyBackupWasFound.php
├── Exceptions
│   ├── CannotCreateDbDumper.php
│   ├── InvalidBackupDestination.php
│   ├── InvalidBackupJob.php
│   ├── InvalidCommand.php
│   ├── InvalidConfiguration.php
│   ├── InvalidHealthCheck.php
│   └── NotificationCouldNotBeSent.php
├── Helpers
│   ├── ConsoleOutput.php
│   ├── File.php
│   ├── Format.php
│   ├── RightAlignedTableStyle.php
│   └── functions.php
├── Listeners
│   └── EncryptBackupArchive.php
├── Notifications
│   ├── BaseNotification.php
│   ├── EventHandler.php
│   ├── Notifiable.php
│   └── Notifications
│       ├── BackupHasFailed.php
│       ├── BackupWasSuccessful.php
│       ├── CleanupHasFailed.php
│       ├── CleanupWasSuccessful.php
│       ├── HealthyBackupWasFound.php
│       └── UnhealthyBackupWasFound.php
└── Tasks
    ├── Backup
    │   ├── BackupJob.php
    │   ├── BackupJobFactory.php
    │   ├── DbDumperFactory.php
    │   ├── FileSelection.php
    │   ├── Manifest.php
    │   └── Zip.php
    ├── Cleanup
    │   ├── CleanupJob.php
    │   ├── CleanupStrategy.php
    │   ├── Period.php
    │   └── Strategies
    └── Monitor
        ├── BackupDestinationStatus.php
        ├── BackupDestinationStatusFactory.php
        ├── HealthCheck.php
        ├── HealthCheckFailure.php
        └── HealthChecks

사용 예


목록, 백업, 백업 삭제


표현
  • 백업 파일 정보 목록
  • 백업
  • 섀도우 파일 삭제
  • https://github.com/bytefury/crater/blob/master/app/Http/Controllers/V1/Backup/BackupsController.php
    <?php
    // Implementation taken from nova-backup-tool - https://github.com/spatie/nova-backup-tool/
    
    namespace Crater\Http\Controllers\V1\Backup;
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Cache;
    use Spatie\Backup\BackupDestination\Backup;
    use Spatie\Backup\BackupDestination\BackupDestination;
    use Spatie\Backup\Helpers\Format;
    use Crater\Jobs\CreateBackupJob;
    use Crater\Rules\Backup\BackupDisk;
    use Crater\Rules\Backup\PathToZip;
    use Illuminate\Http\JsonResponse;
    
    class BackupsController extends ApiController
    {
        /**
         * Display a listing of the resource.
         *
         * @return JsonResponse
         */
        public function index(Request $request)
        {
            $configuredBackupDisks = config('backup.backup.destination.disks');
    
            try {
    	    // BackupDestination = バックアップファイルを表現するクラス。保存機能もこのクラスが担当している。
    	    // ここではバックアップしたファイルの情報をコレクションで取得している
    	    // ページネーションは考慮していないはず。
                $backupDestination = BackupDestination::create(config('filesystems.default'), config('backup.backup.name'));
    
                $backups = Cache::remember("backups-{$request->file_disk_id}", now()->addSeconds(4), function () use ($backupDestination) {
                    return $backupDestination
                        ->backups()
                        ->map(function (Backup $backup) {
                            return [
                                'path' => $backup->path(),
                                'created_at' => $backup->date()->format('Y-m-d H:i:s'),
                                'size' => Format::humanReadableSize($backup->size()),
                            ];
                        })
                        ->toArray();
                });
    
                return response()->json([
                    'backups' => $backups,
                    'disks' => $configuredBackupDisks
                ]);
            } catch (\Exception $e) {
                return response()->json([
                    'backups' => [],
                    'error' => 'invalid_disk_credentials',
                    'error_message' => $e->getMessage(),
                    'disks' => $configuredBackupDisks
                ]);
            }
        }
    
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return JsonResponse
         */
        public function store(Request $request)
        {
            // CreateBackupJobのコードを下に記載
            dispatch(new CreateBackupJob($request->all()))->onQueue(config('backup.queue.name'));
    
            return $this->respondSuccess();
        }
    
        /**
         * Remove the specified resource from storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return JsonResponse
         */
        public function destroy($disk, Request $request)
        {
            $validated = $request->validate([
                'path' => ['required', new PathToZip()],
            ]);
    
            $backupDestination = BackupDestination::create(config('filesystems.default'), config('backup.backup.name'));
    
            $backupDestination
                ->backups()
                ->first(function (Backup $backup) use ($validated) {
                    return $backup->path() === $validated['path'];
                })
                ->delete();
    
            return $this->respondSuccess();
        }
    }
    

    백업


    https://github.com/bytefury/crater/blob/master/app/Jobs/CreateBackupJob.php
    <?php
    
    namespace Crater\Jobs;
    
    use Crater\Models\FileDisk;
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Queue\SerializesModels;
    use Spatie\Backup\Tasks\Backup\BackupJobFactory;
    
    class CreateBackupJob implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        protected $data;
    
        /**
         * Create a new job instance.
         *
         * @return void
         */
        public function __construct($data = '')
        {
           $this->data = $data;
        }
    
        /**
         * Execute the job.
         *
         * @return void
         */
        public function handle()
        {
            $fileDisk = FileDisk::find($this->data['file_disk_id']);
            $fileDisk->setConfig();
    
            $prefix = env('DYNAMIC_DISK_PREFIX', 'temp_');
    
            config(['backup.backup.destination.disks' => [$prefix . $fileDisk->driver]]);
    
            $backupJob = BackupJobFactory::createFromArray(config('backup'));
    
            if ($this->data['option'] === 'only-db') {
                $backupJob->dontBackupFilesystem();
            }
    
            if ($this->data['option'] === 'only-files') {
                $backupJob->dontBackupDatabases();
            }
    
            if (! empty($this->data['option'])) {
                $prefix = str_replace('_', '-', $this->data['option']).'-';
    
                $backupJob->setFilename($prefix.date('Y-m-d-H-i-s').'.zip');
            }
    
            // コード下に記載
            $backupJob->run();
        }
    }
    
    https://github.com/spatie/laravel-backup/blob/master/src/Tasks/Backup/BackupJob.php
    // https://github.com/spatie/laravel-backup/blob/61296bfd8ada78893f926ab6df47d56e0ea3b419/src/Tasks/Backup/BackupJob.php#L128
        public function run()
        {
            $temporaryDirectoryPath = config('backup.backup.temporary_directory') ?? storage_path('app/backup-temp');
    
            $this->temporaryDirectory = (new TemporaryDirectory($temporaryDirectoryPath))
                ->name('temp')
                ->force()
                ->create()
                ->empty();
    
            try {
                if (! count($this->backupDestinations)) {
                    throw InvalidBackupJob::noDestinationsSpecified();
                }
    
                $manifest = $this->createBackupManifest();
    
                if (! $manifest->count()) {
                    throw InvalidBackupJob::noFilesToBeBackedUp();
                }
    
                $zipFile = $this->createZipContainingEveryFileInManifest($manifest);
    
                $this->copyToBackupDestinations($zipFile);
            } catch (Exception $exception) {
                consoleOutput()->error("Backup failed because {$exception->getMessage()}.".PHP_EOL.$exception->getTraceAsString());
    
                $this->sendNotification(new BackupHasFailed($exception));
    
                $this->temporaryDirectory->delete();
    
                throw $exception;
            }
    
            $this->temporaryDirectory->delete();
        }
    

    백업 파일 다운로드


    https://github.com/bytefury/crater/blob/master/app/Http/Controllers/V1/Backup/DownloadBackupController.php
    <?php
    // Implementation taken from nova-backup-tool - https://github.com/spatie/nova-backup-tool/
    
    namespace Crater\Http\Controllers\V1\Backup;
    
    use Crater\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use Spatie\Backup\BackupDestination\Backup;
    use Spatie\Backup\BackupDestination\BackupDestination;
    use Crater\Rules\Backup\BackupDisk;
    use Crater\Rules\Backup\PathToZip;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\HttpFoundation\StreamedResponse;
    
    class DownloadBackupController extends ApiController
    {
        public function __invoke(Request $request)
        {
            $validated = $request->validate([
                'path' => ['required', new PathToZip()],
            ]);
    
            $backupDestination = BackupDestination::create(config('filesystems.default'), config('backup.backup.name'));
    
            $backup = $backupDestination->backups()->first(function (Backup $backup) use ($validated) {
                return $backup->path() === $validated['path'];
            });
    
            if (! $backup) {
                return response('Backup not found', Response::HTTP_UNPROCESSABLE_ENTITY);
            }
    
            return $this->respondWithBackupStream($backup);
        }
    
        public function respondWithBackupStream(Backup $backup): StreamedResponse
        {
            $fileName = pathinfo($backup->path(), PATHINFO_BASENAME);
    
            $downloadHeaders = [
                'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
                'Content-Type' => 'application/zip',
                'Content-Length' => $backup->size(),
                'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
                'Pragma' => 'public',
            ];
    
            return response()->stream(function () use ($backup) {
                $stream = $backup->stream();
    
                fpassthru($stream);
    
                if (is_resource($stream)) {
                    fclose($stream);
                }
            }, 200, $downloadHeaders);
        }
    }
    

    좋은 웹페이지 즐겨찾기