composer如何在无composer命令的生产服务器部署依赖?(本地构建后rsync同步)

1次阅读

不能直接在生产服务器运行 composer install,因生产环境常禁用 shell、缺 php cli 或扩展(如 openssl/zlib),导致 command “install” 未定义或网络解析失败;必须本地构建并严格使用 –no-dev –optimize-autoloader –no-interaction 三参数,rsync 同步时需排除 .git 和各类 tests 目录,但保留 autoload_*.php,并验证 vendor/autoload.php 可被成功 require

composer如何在无composer命令的生产服务器部署依赖?(本地构建后rsync同步)

为什么不能直接在生产服务器运行 composer install

因为生产服务器常禁用 shell 访问、无 PHP CLI 环境、缺扩展(如 opensslzlib),或被安全策略限制执行外部命令。硬上会报错,比如:Command "install" is not definedfile_get_contents(): php_network_getaddresses: getaddrinfo failed——根本连不上 Packagist。

本地构建必须用 --no-dev --optimize-autoloader --no-interaction

这三参数不是可选项,是防止线上出问题的底线:

  • --no-dev:跳过 require-dev 里的包(如 PHPUnit、phpstan),避免把开发工具打进生产环境
  • --optimize-autoloader:生成扁平化 autoload_classmap.php,减少 class_exists() 查找开销,启动快 20%+(尤其 laravel/symfony 项目)
  • --no-interaction:禁掉所有交互提示(比如是否启用插件),否则 CI/脚本会卡住

正确命令:composer install --no-dev --optimize-autoloader --no-interaction。漏掉任一参数,都可能让同步后的代码跑不起来或性能异常。

rsync 同步时要排除哪些目录和文件?

直接 rsync -av ./vendor/ user@prod:/var/www/app/vendor/ 是危险的——会把本地调试痕迹、临时文件甚至 .git 目录一起推上去。

  • 必须排除:vendor/.git(体积大,且无意义)、vendor/*/Tests(测试代码无需上线)
  • 建议排除:vendor/*/testsvendor/*/testvendor/*/phpunit.xml*(大小写不敏感场景下漏掉小写 test 会导致误传)
  • 别忽略:vendor/composer/autoload_*.php —— 这些是 composer dump-autoload 生成的,必须随 vendor 一起同步,否则 Class not found

推荐 rsync 命令片段:rsync -av --exclude='.git' --exclude='*/Tests' --exclude='*/tests' ./vendor/ user@prod:/var/www/app/

部署后还要检查 vendor/autoload.php 是否可 require

常见坑:本地 PHP 版本是 8.2,生产是 7.4,但 composer install 没加 --ignore-platform-reqs,导致某些包降级失败,autoload.php 里引用了不存在的类。

  • 上线后第一件事:在生产机上跑 php -r "require 'vendor/autoload.php'; echo 'OK';"
  • 如果报 ParseErrorClass not found,说明本地构建环境和生产 PHP 版本/扩展不一致
  • 补救方法:本地用和生产一致的 PHP 版本重装依赖(如 docker run --rm -v $(pwd):/app -w /app php:7.4-cli composer install ...

autoload.php 不是“存在就行”,它得能被 PHP 成功解析并注册自动加载器——这是整个依赖链最脆弱的一环。

text=ZqhQzanResources