Envoy 依赖 Composer 的精准配置才能正常运行:全局路径需加入 PATH,部署时须指定用户与目录、同步 composer.lock,多环境用变量控制 --no-dev,且必须关注 Composer 退出码以避免掩盖错误。

Envoy 本身不依赖 Composer 运行,但它的安装、任务中 PHP 命令执行、以及部署流程里 composer install 的行为,全靠你对 Composer 的控制精度决定成败。没配好 Composer,Envoy 要么根本跑不起来,要么在服务器上卡死、权限报错、或装错包。
Envoy 安装时 Composer 全局路径必须生效
你运行 composer global require laravel/envoy 后,envoy 命令能被识别的前提是:~/.composer/vendor/bin(Linux/macOS)或 %USERPROFILE%\AppData\Roaming\Composer\vendor\bin(Windows + WSL2)已加入系统 PATH。
常见错误现象:
- 终端输入
envoy --version报错command not found -
which envoy或where envoy返回空
解决办法:
- 确认全局安装成功:
composer global list | grep envoy - 检查
composer global config bin-dir --absolute输出路径 - 把该路径加进 shell 配置(如
~/.zshrc或~/.bash_profile),然后source一下 - 别用
sudo composer global require—— 权限错乱会导致后续所有命令找不到二进制或写入失败
部署任务里 composer install 必须显式指定用户与工作目录
Envoy 默认以 SSH 登录用户身份执行命令,但该用户可能没有写入 vendor/ 的权限,或未设置 COMPOSER_HOME,导致缓存失效、超时、甚至静默失败。
典型问题:
-
composer install卡住 5–10 分钟后报process-timeout错误 - 提示
Could not write to /root/.composer/cache(尤其用 root 登录时) - 装出来的
vendor/权限为 root,PHP-FPM 无法加载
实操建议:
- 始终用非 root 用户(如
www-data所属用户)登录 SSH,并确保其对项目目录有完整读写权 - 在
@task中显式切换目录:cd /var/www/myapp && ...,不要依赖默认路径 - 加
--no-interaction --prefer-dist --optimize-autoloader参数,减少交互和体积 - 必要时前置设置环境变量:
COMPOSER_HOME=/home/deploy/.composer COMPOSER_CACHE_DIR=/home/deploy/.composer/cache composer install ...
composer.json 和 composer.lock 必须随 Git 提交并保持同步
Envoy 不会帮你生成或更新 composer.lock。如果你只提交了 composer.json,而服务器上执行的是 composer install,它会按 lock 文件还原——但 lock 文件不存在,就会退化成 composer update 行为,结果不可控。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
后果包括:
- 不同服务器装出不同版本的包(比如
monolog从 2.x 升到 3.x,API 不兼容) - 部署失败后查不出原因,因为本地
composer install成功,但服务器上因网络/镜像源差异失败 -
php artisan命令直接报Class not found
关键动作:
- 每次改完
composer.json,本地必须运行composer update --lock或composer install生成新composer.lock -
composer.lock必须git add并提交,不能忽略 - 如果使用私有包或自定义镜像源,确保服务器上
~/.composer/auth.json和config.json已配置好,否则install会认证失败
多环境部署时,composer install 的 --no-dev 别硬编码
开发环境需要 phpunit、laravel/pint 等,生产环境不该装。但写死 --no-dev 会让 staging 环境也丢掉调试工具,排查问题变困难。
更灵活的做法是用 Envoy 变量控制:
@task('deploy', ['on' => 'web'])
cd /var/www/app
@if($env === 'production')
composer install --no-dev --no-interaction --prefer-dist
@else
composer install --no-interaction --prefer-dist
@endif
php artisan migrate --force
@endtask
然后这样调用:
envoy run deploy --env=productionenvoy run deploy --env=staging
注意:$env 是纯字符串,不会自动映射到 Laravel 的 APP_ENV,你要自己在任务里设环境变量或写入 .env。
真正容易被忽略的是:Composer 的退出码。Envoy 默认只要某条命令返回非 0 就中断整个任务,但有些 Composer 命令(比如 composer install 在部分插件失败时仍返回 0),或者你用了 || true 掩盖错误——这会让后续的 php artisan 在缺失依赖的情况下继续执行,最终报错位置完全偏离真实原因。


















