Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deployment of Laravel app breaks the app until composer install is manually run

I have a Laravel app using Passport to provide API authentication. The app is deployed using git with a post-receive hook. Part of the post-receive script is a composer install. Ever since I've included Passport, whenever I deploy my app the API breaks on routes that are behind an authentication gate, with the stack trace pasted below.

When I go in to the app's server and run the exact same composer install command as is in my post-receive hook, then things work fine again.

I don't see any error messages from git when the deploy happens, and it appears that I get the same output from composer install when the deploy happens and when I run the command manually.

Here's the deploy output from the composer install command:

remote: Loading composer repositories with package information        
remote: Installing dependencies (including require-dev) from lock file        
remote: Nothing to install or update        
remote: Generating autoload files        
remote: > php artisan clear-compiled        
remote: The compiled class file has been removed.        
remote: > php artisan optimize        
remote: Generating optimized class loader        
remote: Compiling common classes

And here's what I see when I run the command manually:

Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Nothing to install or update
Generating autoload files
> php artisan clear-compiled
The compiled class file has been removed.
> php artisan optimize
Generating optimized class loader
Compiling common classes

What's going on here? It seems that the deploy is installing an older version of some component of Passport that is then corrected after running composer install manually, but I am at a loss as to why this would be happening, and especially why it would happen each time I deploy a new update, even if there are no changes to composer.json or composer.lock.

Here's the stack trace referred to above:

[2017-01-04 20:36:37] production.ERROR: exception 'BadMethodCallException' with message 'Call to undefined method Illuminate\Database\Query\Builder::withAccessToken()' in /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2450
Stack trace:
#0 [internal function]: Illuminate\Database\Query\Builder->__call('withAccessToken', Array)
#1 [internal function]: Illuminate\Database\Query\Builder->withAccessToken(Object(Laravel\Passport\Token))
#2 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1469): call_user_func_array(Array, Array)
#3 [internal function]: Illuminate\Database\Eloquent\Builder->__call('withAccessToken', Array)
#4 [internal function]: Illuminate\Database\Eloquent\Builder->withAccessToken(Object(Laravel\Passport\Token))
#5 /home/portalvarius/app/production/bootstrap/cache/compiled.php(11801): call_user_func_array(Array, Array)
#6 /home/portalvarius/app/production/vendor/laravel/passport/src/Guards/TokenGuard.php(139): Illuminate\Database\Eloquent\Model->__call('withAccessToken', Array)
#7 /home/portalvarius/app/production/vendor/laravel/passport/src/Guards/TokenGuard.php(139): App\Models\User->withAccessToken(Object(Laravel\Passport\Token))
#8 /home/portalvarius/app/production/vendor/laravel/passport/src/Guards/TokenGuard.php(90): Laravel\Passport\Guards\TokenGuard->authenticateViaBearerToken(Object(Illuminate\Http\Request))
#9 /home/portalvarius/app/production/vendor/laravel/passport/src/PassportServiceProvider.php(251): Laravel\Passport\Guards\TokenGuard->user(Object(Illuminate\Http\Request))
#10 [internal function]: Laravel\Passport\PassportServiceProvider->Laravel\Passport\{closure}(Object(Illuminate\Http\Request))
#11 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Auth/RequestGuard.php(53): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#12 /home/portalvarius/app/production/bootstrap/cache/compiled.php(544): Illuminate\Auth\RequestGuard->user()
#13 /home/portalvarius/app/production/bootstrap/cache/compiled.php(548): Illuminate\Auth\RequestGuard->check()
#14 /home/portalvarius/app/production/app/Http/Middleware/Authenticate.php(20): Illuminate\Auth\RequestGuard->guest()
#15 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10052): App\Http\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure), 'api')
#16 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#17 /home/portalvarius/app/production/Api/V1/Http/Middleware/LogApiAccess.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#18 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10052): Api\V1\Http\Middleware\LogApiAccess->handle(Object(Illuminate\Http\Request), Object(Closure))
#19 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#20 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10160): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#21 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10052): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#22 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#23 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#24 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10052): Illuminate\Routing\Middleware\ThrottleRequests->handle(Object(Illuminate\Http\Request), Object(Closure), '60', '1')
#25 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#26 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10037): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#27 /home/portalvarius/app/production/bootstrap/cache/compiled.php(8339): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#28 /home/portalvarius/app/production/bootstrap/cache/compiled.php(8330): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#29 /home/portalvarius/app/production/bootstrap/cache/compiled.php(8321): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#30 /home/portalvarius/app/production/bootstrap/cache/compiled.php(2575): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#31 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#32 /home/portalvarius/app/production/bootstrap/cache/compiled.php(3371): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#33 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10052): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#34 /home/portalvarius/app/production/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#35 /home/portalvarius/app/production/bootstrap/cache/compiled.php(10037): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#36 /home/portalvarius/app/production/bootstrap/cache/compiled.php(2519): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#37 /home/portalvarius/app/production/bootstrap/cache/compiled.php(2503): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#38 /home/portalvarius/app/production/public/index.php(54): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#39 {main}        
like image 276
ralbatross Avatar asked Jan 04 '17 20:01

ralbatross


1 Answers

Ok, so the issue was in the artisan optimize command. As I indicated in the comment on my question, I noticed that the optimize command was running much quicker via the post-receive hook than when manually running the command.

In my deployed environment, I have a composer.phar file in a directory separate from the base laravel directory. When I made a softlink to composer.phar in the base directory everything worked fine again.

I'm still not sure why the issue happened, but it seems like Laravel was maybe not able to find my composer instance when running from the post-receive hook even though my environment was set up such that the same command run from the commandline worked fine.

like image 113
ralbatross Avatar answered Sep 17 '22 17:09

ralbatross