I'm having an issue upgrading a Government client from Laravel 5.1 to Laravel 5.5 with the Spatie Backups.
The backup command pushes the DB backup to S3. The S3 credentials that the application has are special write-only keys. Using these keys you cannot "list" or "read" from the S3 box - just push new data to it.
The reason is an extra layer of security; if the web server was compromised for any reason - the attacker cannot get to the backups to encrypt them. i.e. it's a form of ransomware protection and we "island" the backups away from everything else.
But somewhere between Laravel 5.1 and Laravel 5.5 - the associate Spatie Backup seems to want to always "list" the backup after posting it? This causing an S3 error. i.e. the backup works and is placed at S3 - but then throws an error because it cant list the bucket.
I've tried the following in my config - but it doesnt stop the package from wanting to list.
'monitorBackups' => [ ],
'cleanup' => [ ],
Is there any flags that I've missed to disable?
p.s. I know this means we miss out on some of the cool features around cleanups etc - but we monitor the backups using a different tool to keep it seperate from the web server.
Could you give a stack trace of the error so we know where that listing is done?
I'd accept a PR that adds a sort of read only mode to the backup command.
@freekmurze - sorry - here is the console dump:
I'll dig through it and see if there's an easy PR. Or if there is some way in the existing config to stop it - let me know.
Thanks,
vagrant@homestead:~/www/laravel $ artisan backup:run --only-db
Starting backup...
Dumping database my_app...
Gzipping my_app...
Determining files to backup...
Zipping 1 files...
Created zip containing 1 files. Size is 31.84 KB
Copying zip to disk named s3...
Successfully copied zip to disk named s3.
Copying zip failed because: Error executing "ListObjects" on "https://mydomain.s3.ap-southeast-2.amazonaws.com/?prefix=APP_NAME%2F&encoding-type=url"; AWS HTTP error: Client error: `GET https://mydomain.s3.ap-southeast-2.amazonaws.com/?prefix=APP_NAME%2F&encoding-type=url` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>56CF09 (truncated...)
AccessDenied (client): Access Denied - <?xml version="1.0" encoding="UTF-8"?>
<Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>AAAAA</RequestId><HostId>ReyAAAAAAAAAAA4=</HostId>.
Backup failed because Error executing "ListObjects" on "https://mydomain.s3.ap-southeast-2.amazonaws.com/?prefix=PTS_APP%2F&encoding-type=url"; AWS HTTP error: Client error: `GET https://APPtest.s3.ap-southeast-2.amazonaws.com/?prefix=PTS_APP%2F&encoding-type=url` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>351269 (truncated...)
AccessDenied (client): Access Denied - <?xml version="1.0" encoding="UTF-8"?>
<Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>refgreregg</RequestId><HostId>regergergregrge</HostId>.
#0 /home/vagrant/laravel/vendor/aws/aws-sdk-php/src/WrappedHttpHandler.php(100): Aws\WrappedHttpHandler->parseError(Array, Object(GuzzleHttp\Psr7\Request), Object(Aws\Command), Array)
#1 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(203): Aws\WrappedHttpHandler->Aws\{closure}(Array)
#2 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(174): GuzzleHttp\Promise\Promise::callHandler(2, Array, Array)
#3 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/RejectedPromise.php(40): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}(Array)
#4 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/TaskQueue.php(47): GuzzleHttp\Promise\RejectedPromise::GuzzleHttp\Promise\{closure}()
#5 /home/vagrant/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(96): GuzzleHttp\Promise\TaskQueue->run()
#6 /home/vagrant/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(123): GuzzleHttp\Handler\CurlMultiHandler->tick()
#7 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#8 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
#9 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
#10 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#11 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
#12 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#13 /home/vagrant/laravel/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#14 /home/vagrant/laravel/vendor/aws/aws-sdk-php/src/AwsClientTrait.php(58): GuzzleHttp\Promise\Promise->wait()
#15 /home/vagrant/laravel/vendor/aws/aws-sdk-php/src/ResultPaginator.php(127): Aws\AwsClient->execute(Object(Aws\Command))
#16 /home/vagrant/laravel/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php(281): Aws\ResultPaginator->valid()
#17 /home/vagrant/laravel/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php(264): League\Flysystem\AwsS3v3\AwsS3Adapter->retrievePaginatedListing(Array)
#18 /home/vagrant/laravel/vendor/league/flysystem/src/Filesystem.php(271): League\Flysystem\AwsS3v3\AwsS3Adapter->listContents('PTS_APP', true)
#19 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php(544): League\Flysystem\Filesystem->listContents('PTS_APP', true)
#20 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php(557): Illuminate\Filesystem\FilesystemAdapter->files('PTS_APP', true)
#21 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/BackupDestination/BackupDestination.php(103): Illuminate\Filesystem\FilesystemAdapter->allFiles('PTS_APP')
#22 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/BackupDestination/BackupDestination.php(143): Spatie\Backup\BackupDestination\BackupDestination->backups()
#23 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Notifications/BaseNotification.php(46): Spatie\Backup\BackupDestination\BackupDestination->newestBackup()
#24 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Notifications/Notifications/BackupHasFailed.php(25): Spatie\Backup\Notifications\BaseNotification->backupDestinationProperties()
#25 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(50): Spatie\Backup\Notifications\Notifications\BackupHasFailed->toMail(Object(Spatie\Backup\Notifications\Notifiable))
#26 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(113): Illuminate\Notifications\Channels\MailChannel->send(Object(Spatie\Backup\Notifications\Notifiable), Object(Spatie\Backup\Notifications\Notifications\BackupHasFailed))
#27 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(89): Illuminate\Notifications\NotificationSender->sendToNotifiable(Object(Spatie\Backup\Notifications\Notifiable), 'c0reregg5c-4...', Object(Spatie\Backup\Notifications\Notifications\BackupHasFailed), 'mail')
#28 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(64): Illuminate\Notifications\NotificationSender->sendNow(Array, Object(Spatie\Backup\Notifications\Notifications\BackupHasFailed))
#29 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(35): Illuminate\Notifications\NotificationSender->send(Array, Object(Spatie\Backup\Notifications\Notifications\BackupHasFailed))
#30 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php(18): Illuminate\Notifications\ChannelManager->send(Object(Spatie\Backup\Notifications\Notifiable), Object(Spatie\Backup\Notifications\Notifications\BackupHasFailed))
#31 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Notifications/EventHandler.php(33): Spatie\Backup\Notifications\Notifiable->notify(Object(Spatie\Backup\Notifications\Notifications\BackupHasFailed))
#32 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(350): Spatie\Backup\Notifications\EventHandler->Spatie\Backup\Notifications\{closure}(Object(Spatie\Backup\Events\BackupHasFailed))
#33 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(200): Illuminate\Events\Dispatcher->Illuminate\Events\{closure}('Spatie\\Backup\\E...', Array)
#34 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(465): Illuminate\Events\Dispatcher->dispatch('Spatie\\Backup\\E...')
#35 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Tasks/Backup/BackupJob.php(255): event(Object(Spatie\Backup\Events\BackupHasFailed))
#36 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Tasks/Backup/BackupJob.php(247): Spatie\Backup\Tasks\Backup\BackupJob->sendNotification(Object(Spatie\Backup\Events\BackupHasFailed))
#37 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Support/Collection.php(339): Spatie\Backup\Tasks\Backup\BackupJob->Spatie\Backup\Tasks\Backup\{closure}(Object(Spatie\Backup\BackupDestination\BackupDestination), 0)
#38 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Tasks/Backup/BackupJob.php(249): Illuminate\Support\Collection->each(Object(Closure))
#39 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Tasks/Backup/BackupJob.php(137): Spatie\Backup\Tasks\Backup\BackupJob->copyToBackupDestinations('/home/vagrant/w...')
#40 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Commands/BackupCommand.php(49): Spatie\Backup\Tasks\Backup\BackupJob->run()
#41 [internal function]: Spatie\Backup\Commands\BackupCommand->handle()
#42 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(29): call_user_func_array(Array, Array)
#43 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#44 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#45 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php(549): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#46 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Console/Command.php(183): Illuminate\Container\Container->call(Array)
#47 /home/vagrant/laravel/vendor/symfony/console/Command/Command.php(252): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#48 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Console/Command.php(170): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#49 /home/vagrant/laravel/vendor/spatie/laravel-backup/src/Commands/BaseCommand.php(22): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#50 /home/vagrant/laravel/vendor/symfony/console/Application.php(938): Spatie\Backup\Commands\BaseCommand->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#51 /home/vagrant/laravel/vendor/symfony/console/Application.php(240): Symfony\Component\Console\Application->doRunCommand(Object(Spatie\Backup\Commands\BackupCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#52 /home/vagrant/laravel/vendor/symfony/console/Application.php(148): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#53 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Console/Application.php(88): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#54 /home/vagrant/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(121): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#55 /home/vagrant/laravel/artisan(35): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#56 {main}
Backup completed!
Ok - so I traced it down to the package firing the event BackupWasSuccessful triggers the list somehow. I couldnt really see how - but it does.
So the following command solves my problem:
backup:run --only-db --disable-notifications
@freekmurze - do you want to close this issue? I dont see why sending a notification triggers a list on the S3 object? Feel free to close if you want.
On first glace I don't see it either why sending a notification triggers that list operation. Closing this for now as your problem is solved.
Most helpful comment
Ok - so I traced it down to the package firing the event
BackupWasSuccessfultriggers the list somehow. I couldnt really see how - but it does.So the following command solves my problem:
backup:run --only-db --disable-notifications@freekmurze - do you want to close this issue? I dont see why sending a notification triggers a list on the S3 object? Feel free to close if you want.