composer install --no-dev是上线必加参数,因它跳过phpunit等dev依赖,避免30%~60%体积膨胀、安全风险及autoload性能下降,且需配合权限加固与discard-changes: true共同生效。

生产环境的 vendor 目录必须干净、最小化、不可写,且不能依赖手动干预重建。
为什么 composer install --no-dev 是上线必加参数
开发依赖(如 phpunit、phpstan、mockery)在运行时完全无用,却常占 vendor/ 体积的 30%~60%。不加 --no-dev,等于把测试工具、静态分析器、本地调试器全打包进线上容器或服务器。
- CI/CD 流水线里漏掉它,镜像层会多出几十 MB,启动变慢,攻击面扩大
-
composer.json中require-dev的包若含可执行文件(如php-cs-fixer),它们仍会出现在vendor/bin/,但源码和tests/目录不会被下载——前提是--no-dev生效 - 某些包(如 Laravel)的
post-autoload-dump脚本在--no-dev下可能跳过部分服务提供者注册,需验证实际行为,而非假设“只是少几个类”
vendor/ 权限必须限制为只读,且禁止全局可写
默认情况下,composer install 不改权限;若用 root 或高权限用户执行,vendor/ 下 PHP 文件可能变成 664 或 666,vendor/bin/ 下脚本可能变成 775——这等于给任意代码执行漏洞开了后门。
- 部署前必须设
umask 0022,确保新建文件为644、目录为755 - 安装完成后立即执行:
find vendor/ -type f -exec chmod 644 {} \;和find vendor/ -type d -exec chmod 755 {} \; -
vendor/bin/*需单独加固:chmod 755 vendor/bin/*(可执行但不可写) - Web 服务器(如 PHP-FPM)不应以部署用户身份运行;推荐将
www-data加入部署用户组,再用chmod -R g+rX vendor/,而非放宽为775
discard-changes: true 能安全省下 15%~25% 空间
Composer 默认为每个包保留完整 Git 元数据(.git/ 目录),用于支持 composer update 时的本地修改合并。生产环境永远不需要这个功能。
- 在
composer.json的config段添加:"discard-changes": true - 已有
vendor/不会自动清理,必须先rm -rf vendor,再重新composer install --no-dev - 副作用是:你不能再对
vendor/内任意包做本地 patch 并期望composer update保留它——这本来就是反模式,应改用patches插件或 fork 后 require
别碰 vendor/ 里的文件,也别改 vendor-dir
vendor/ 是 Composer 硬编码路径,不是配置项。试图通过 "vendor-dir": "libs" 改位置,只会让 IDE、静态分析器、CI 脚本全部失效,且极易引发 Class not found。
- 所有命令(
install、update、dump-autoload)必须在composer.json所在目录执行,否则vendor/会生成在错误位置 -
vendor/autoload.php是唯一入口,必须在项目启动时require一次,且不能include_once多次 - 删了
vendor/composer/下的autoload_*.php文件会导致自动加载失败,修复方式是composer dump-autoload --optimize,不是重装
最常被忽略的是:权限加固必须在 composer install 后立刻执行,而不是“等部署完再处理”;而 --no-dev 必须进入 CI/CD 基础镜像或部署脚本的固定流程,不能靠人工记忆。


















