As of Laravel 5.6, artisan optimize should no longer be executed, but task artisan:optimize executes it in versions prior to 5.5 and in the same or after 5.7. I think the second condition should not be, since doing it with a 5.8 fails.
I'm working on first LTS release of Deployer.
Please, consider supporting Deployer development on Patreon page:
https://www.patreon.com/deployer
| Q | A
| ----------------- | ---
| Issue Type | Bug
| Deployer Version | 6.2.0
| Local Machine OS | Ubuntu 18.04.2 LTS
| Remote Machine OS | Ubuntu 18.04.2 LTS
| Docker Version | 18.09.2, build 6247962
| Docker Compose Version | 1.24.0, build 0aa59064
| PHP Container | digitalocean.com/php
If you're reporting a bug, please include following information
deploy.phptask('artisan:optimize', function () {
$deprecatedVersion = 5.5;
$readdedInVersion = 5.7;
$currentVersion = get('laravel_version');
writeln('Laravel version: ' . $currentVersion);
if (
version_compare($currentVersion, $deprecatedVersion, '<') ||
version_compare($currentVersion, $readdedInVersion, '>=')
) {
writeln('RUN optimize');
run('{{bin/php}} {{deploy_path}}/current/artisan optimize');
}
});
➤ Executing task artisan:optimize
Laravel version: 5.8.17
RUN optimize
[laraveldocker.ltwtest.com] > cd /var/www/current/ && docker-compose exec -T app php /var/www/current/artisan optimize
[laraveldocker.ltwtest.com] < Configuration cache cleared!
[laraveldocker.ltwtest.com] < Configuration cached successfully!
[laraveldocker.ltwtest.com] < Route cache cleared!
[laraveldocker.ltwtest.com] < In Route.php line 917:
[laraveldocker.ltwtest.com] < Unable to prepare route [api/user] for serialization. Uses Closure.
➤ Executing task deploy:failed
• done on [laraveldocker.ltwtest.com]
✔ Ok [0ms]
➤ Executing task deploy:unlock
[laraveldocker.ltwtest.com] > rm -f /var/www/.dep/deploy.lock
• done on [laraveldocker.ltwtest.com]
✔ Ok [96ms]
In Client.php line 99:
[DeployerExceptionRuntimeException (1)]
The command "cd /var/www/current/ && docker-compose exec -T app php /var/www/current/artisan optimize" failed.
Exit Code: 1 (General error)
Host Name: laraveldocker.ltwtest.com
================
Configuration cache cleared!
Configuration cached successfully!
Route cache cleared!
In Route.php line 917:
Unable to prepare route [api/user] for serialization. Uses Closure.
Exception trace:
DeployerSshClient->run() at phar:///usr/local/bin/dep/src/functions.php:304
Deployerrun() at /home/xavier/Documents/Projects/laravel-docker/deployer/recipe/laravel_docker.php:125
DeployerDeployer::Deployer{closure}() at n/a:n/a
call_user_func() at phar:///usr/local/bin/dep/src/Task/Task.php:105
DeployerTaskTask->run() at phar:///usr/local/bin/dep/src/Executor/SeriesExecutor.php:63
DeployerExecutorSeriesExecutor->run() at phar:///usr/local/bin/dep/src/Console/TaskCommand.php:142
DeployerConsoleTaskCommand->execute() at phar:///usr/local/bin/dep/vendor/symfony/console/Command/Command.php:252
SymfonyComponentConsoleCommandCommand->run() at phar:///usr/local/bin/dep/vendor/symfony/console/Application.php:946
SymfonyComponentConsoleApplication->doRunCommand() at phar:///usr/local/bin/dep/src/Console/Application.php:133
DeployerConsoleApplication->doRunCommand() at phar:///usr/local/bin/dep/vendor/symfony/console/Application.php:248
SymfonyComponentConsoleApplication->doRun() at phar:///usr/local/bin/dep/vendor/symfony/console/Application.php:148
SymfonyComponentConsoleApplication->run() at phar:///usr/local/bin/dep/src/Deployer.php:331
DeployerDeployer::run() at phar:///usr/local/bin/dep/bin/dep:119
require() at /usr/local/bin/dep:4
deploy [-p|--parallel] [-l|--limit LIMIT] [--no-hooks] [--log LOG] [--roles ROLES] [--hosts HOSTS] [-o|--option OPTION] [--] [
Same error here, laravel v5.7.*
It isn't the deployer error. The "artisan:optimize" task calls "route:cache" command to save all application routes to one file at Laravel bootstrap/cache directory.
The default routes/api.php defines a closure like this.
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Closure could not be serialized, that is why the exception is thrown with the message "Unable to prepare route [api/user] for serialization. Uses Closure.". You have to remove or replace all route Closures.
This is a deployer error. The current Laravel recipe by default calls the 'artisan:optimize' task - a command Laravel no longer recommends and out of the box doesn't work with (Hence the route closure errors).
If you are using with a laravel version after 5.7 you have to override the deployer included recipe to avoid running the deprecated "artisan:optimize" task. Based on my experience in the last hour this is confusing to realise, as the errors highlight the issue as the routes file, not that deployer is running a deprecated command.
The easy fix would be to remove the dead "artisan:optimize" task from the default recipe, but unclear how that will affect existing 5.x users who can use the optimize command?
Alternatively is there a way to run the task only on appropriate versions of Laravel? Seems silly to have a default recipe that actively doesn't work with the default setup of the current version of Laravel.
Let's make it optional in recipe.
Also I'm thinking to moving away of common recipes for frameworks. It should be just templates.
@hennell-git just ran into this as well. How do you "override the deployer included recipe" as you mentioned?
Like this:
task('artisan:optimize', function () {});
I solved the problem by making sure that my routes(web and api) does not have closure callbacks
There are route caching docs for Laravel > https://laravel.com/docs/5.8/controllers#route-caching
First important thing there is all about closures..
Deployer can't resolve issues defined by the software/framework itself..
Fixed in master. Please verify.
Tried to help out and verify just using a new default laravel app and deploying to a local folder.
localhost()->stage() doesn't exist anymore, tried to follow src changes to guess how you set a stage name now, but all your commits are labeled things like 🐳🦄🐍 and touch everything, so gave up trying to work it out. 🤷♂️Based on the Laravel.php recipe change (commit message "🍯" ) I would guess it isn't fixed:
task('artisan:optimize', artisan('optimize', ['min' => 5.7]));
should probably be:
task('artisan:optimize', artisan('optimize', ['**max**' => 5.7]));
as that's the last version optimise works on, but unverified as master has other issues.
Yes, master currently difficult to follow. I'm going to squash everything and wrtie better changelog.
Also I'm testing via deploying latest laravel. Also now is best time to get thinks fixed.
host(...)->set('labels', ['stage' => 'prod']);
<?php
namespace Deployer;
require 'recipe/laravel.php';
// Config
set('application', 'blog');
set('deploy_path', function () {
return '~/' . currentHost()->alias();
});
set('repository', '[email protected]');
add('shared_files', []);
add('shared_dirs', []);
add('writable_dirs', []);
// Hosts
set('identity_file', '~/.ssh/id_rsa');
set('sudo_pass', ...');
set('labels', ['app' => 'web']);
host('prod')->set('hostname', '...');
host('beta')->set('hostname', '...');
host('test')->set('hostname', '...');
host('monitoring')->set('hostname', '...')->set('labels', ['app' => 'monit']);
// Tasks
task('deploy')->select('app=web');
task('build', function () {
run('cd {{release_path}} && npm run build');
});
task('upload', function () {
upload('/Users/anton/dev/blog', '~/' . time());
});
task('download', function () {
download('~', '/Users/anton/dev/blog/downloaded');
});
// If deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');
task('uptime', function () {
run('uptime -p');
})->once()->select('host=monitoring');
before('deploy', 'uptime');
task('deploy:symlink')->limit(1);
task('reload:nginx', function () {
run('sudo nginx -s reload');
});
task('test', function () {
run('echo {{deploy_path}}');
on(Deployer::get()->hosts, function () {
set('foo', run('echo {{deploy_path}}'));
});
})->once();
task('date', function () {
run('while true; do date; sleep 1; done', ['idle_timeout' => 2]);
});
task('config', function () {
var_dump(currentHost()->getConfig());
});
Most helpful comment
Like this: