Deployer部署Laravel时Composer异常:提示无更新但终端执行正常
嘿,我一眼就揪出你这个问题的根源了——你自定义的deploy:composer_install任务写法有问题!
问题出在哪?
你把目录切换和Composer命令拆成了两个独立的run()调用:
task('deploy:composer_install', function () { run('cd {{release_path}} '); // 这行切换目录只在当前shell会话生效 run('composer install'); // 这行是新开了一个shell,回到了用户主目录! })->desc('running composer install');
Deployer的每个run()方法都会启动一个全新的Shell会话,所以第一个cd的效果到第二个命令就完全失效了。此时Composer是在你的服务器用户主目录下执行的,而不是项目的release目录,自然会提示Nothing to install or update。
修复方案
有两种靠谱的解决方式,推荐用第二种更符合Deployer最佳实践的:
方案1:合并命令到同一个run()里
把两个命令用&&连接,确保在同一个Shell会话中执行:
task('deploy:composer_install', function () { run('cd {{release_path}} && composer install'); })->desc('running composer install');
方案2:直接用Deployer内置的Composer任务
Laravel的Deployer Recipe已经内置了deploy:vendors任务,专门用来处理Composer安装,比自己写的更稳定可靠,还能自动处理目录、默认参数等问题。你可以直接删掉自定义的deploy:composer_install任务,然后调整任务顺序:
// 删掉你自定义的deploy:composer_install任务 // 把原来的after('deploy:symlink', 'deploy:composer_install')替换成: after('deploy:update_code', 'deploy:vendors');
默认情况下,deploy:vendors会执行composer install --no-dev --optimize-autoloader --no-interaction --no-progress,如果需要修改参数,可以通过配置项调整:
set('composer_options', '--no-dev --optimize-autoloader --no-interaction --no-progress --prefer-dist');
额外提醒
你原来的任务时机也不对:after('deploy:symlink', 'deploy:composer_install')是在已经切换到新发布版本之后才执行Composer,这其实不合理——依赖包应该在代码更新完成后、切换版本前就安装好,这样能避免发布过程中出现依赖缺失的问题。用内置的deploy:vendors的话,默认时机就是在deploy:update_code之后,刚好合适。
我使用Deployer部署Laravel应用,其余环节均运行正常,但Composer始终提示:
Nothing to install or update
然而通过终端进入同一目录时,Composer可正常安装所有依赖包。请问我的deploy.php配置是否存在遗漏?
内容的提问来源于stack exchange,提问作者Peter

