如何将Composer项目部署到生产环境并排除dev依赖的正确方法?
- 内容介绍
- 文章标签
- 相关推荐
本文共计931个文字,预计阅读时间需要4分钟。
composer install --no-dev 是必须使用的命令,其他方式都不算真正生效。它不是可选项,而是生产部署的硬性要求;省略这个参数,相当于直接将本地开发环境的服务器直接部署,这可能会导致生产环境出现问题。
为什么 --no-dev 是唯一可靠方式
这个参数直接告诉 Composer:跳过 require-dev 区块里的所有包,不解析、不下载、不写入 vendor/。它不依赖环境变量、不靠缓存清理、也不看配置文件是否“看起来干净”。
-
COMPOSER_NO_DEV=1在 Composer 2.2+ 中已被弃用,行为不稳定,CI 脚本里设了也可能被覆盖 - 只删
composer.json里的require-dev没用——composer.lock里还存着旧记录,install会照装 - 先跑一次没带
--no-dev的install,再补加参数也没用——已装的phpunit不会自动卸载
composer.lock 文件必须“干净”才真正起效
--no-dev 只在 composer.lock 本身不含 dev 包时才顺利执行;如果 lock 文件里已有 phpunit/phpunit 的 dist 条目,install --no-dev 会报错:“dev dependencies not found”。
- 首次上线前,应在干净环境(无
vendor/、无composer.lock)运行:composer update --no-dev --lock,再提交 lock 文件 - CI 脚本中建议加一步:
git clean -xffd vendor/ && rm -f composer.lock,避免复用污染过的缓存 - 检查 lock 文件是否干净:打开后搜
"packages": [,再确认里面没有phpunit、phpstan、symfony/debug-bundle等包名
部署后必须验证,不能只信命令行输出
命令跑完不代表成功——得进服务器或容器里看真实结果。常见误判是看到 vendor/autoload.php 还在,就以为一切正常。
- 执行:
ls vendor/ | grep -E "phpunit|mockery|symfony\/debug",输出应为空 - 运行:
composer show --dev,应提示 “No dependencies installed for development” 或直接报错 “Command 'show' is not defined” - 检查
vendor/composer/autoload_static.php或autoload_classmap.php,确认里面没有来自tests/或Tests/的路径映射(否则说明autoload-dev规则仍被加载)
别忘了清理 vendor/ 里残留的危险内容
--no-dev 只控制“装不装包”,但很多安全隐患藏在已安装包的子目录里:比如 vendor/bin/phpunit、vendor/symfony/console/Tests/、vendor/doctrine/orm/.git。
- 部署脚本中加清理命令:
rm -rf vendor/bin/ vendor/**/tests/ vendor/**/Tests/ vendor/**/test/ vendor/**/Test/ vendor/**/.git vendor/**/phpunit.xml vendor/composer/installed.json - Linux/macOS 下可用:
find vendor -path '*/tests' -o -path '*/.git' -o -name 'phpunit.xml' -delete,但 CI 中推荐显式rm -rf,避免 glob 漏匹配 - 特别注意
vendor/composer/installed.json:它含所有包的完整版本和哈希,泄露后可辅助攻击者判断漏洞,必须删
真正难的不是加参数,而是让整个流程(本地生成 lock、CI 构建、镜像打包、线上验证)全部对齐——只要其中一环用了没带 --no-dev 的缓存,phpunit 就可能悄悄混进生产环境。
本文共计931个文字,预计阅读时间需要4分钟。
composer install --no-dev 是必须使用的命令,其他方式都不算真正生效。它不是可选项,而是生产部署的硬性要求;省略这个参数,相当于直接将本地开发环境的服务器直接部署,这可能会导致生产环境出现问题。
为什么 --no-dev 是唯一可靠方式
这个参数直接告诉 Composer:跳过 require-dev 区块里的所有包,不解析、不下载、不写入 vendor/。它不依赖环境变量、不靠缓存清理、也不看配置文件是否“看起来干净”。
-
COMPOSER_NO_DEV=1在 Composer 2.2+ 中已被弃用,行为不稳定,CI 脚本里设了也可能被覆盖 - 只删
composer.json里的require-dev没用——composer.lock里还存着旧记录,install会照装 - 先跑一次没带
--no-dev的install,再补加参数也没用——已装的phpunit不会自动卸载
composer.lock 文件必须“干净”才真正起效
--no-dev 只在 composer.lock 本身不含 dev 包时才顺利执行;如果 lock 文件里已有 phpunit/phpunit 的 dist 条目,install --no-dev 会报错:“dev dependencies not found”。
- 首次上线前,应在干净环境(无
vendor/、无composer.lock)运行:composer update --no-dev --lock,再提交 lock 文件 - CI 脚本中建议加一步:
git clean -xffd vendor/ && rm -f composer.lock,避免复用污染过的缓存 - 检查 lock 文件是否干净:打开后搜
"packages": [,再确认里面没有phpunit、phpstan、symfony/debug-bundle等包名
部署后必须验证,不能只信命令行输出
命令跑完不代表成功——得进服务器或容器里看真实结果。常见误判是看到 vendor/autoload.php 还在,就以为一切正常。
- 执行:
ls vendor/ | grep -E "phpunit|mockery|symfony\/debug",输出应为空 - 运行:
composer show --dev,应提示 “No dependencies installed for development” 或直接报错 “Command 'show' is not defined” - 检查
vendor/composer/autoload_static.php或autoload_classmap.php,确认里面没有来自tests/或Tests/的路径映射(否则说明autoload-dev规则仍被加载)
别忘了清理 vendor/ 里残留的危险内容
--no-dev 只控制“装不装包”,但很多安全隐患藏在已安装包的子目录里:比如 vendor/bin/phpunit、vendor/symfony/console/Tests/、vendor/doctrine/orm/.git。
- 部署脚本中加清理命令:
rm -rf vendor/bin/ vendor/**/tests/ vendor/**/Tests/ vendor/**/test/ vendor/**/Test/ vendor/**/.git vendor/**/phpunit.xml vendor/composer/installed.json - Linux/macOS 下可用:
find vendor -path '*/tests' -o -path '*/.git' -o -name 'phpunit.xml' -delete,但 CI 中推荐显式rm -rf,避免 glob 漏匹配 - 特别注意
vendor/composer/installed.json:它含所有包的完整版本和哈希,泄露后可辅助攻击者判断漏洞,必须删
真正难的不是加参数,而是让整个流程(本地生成 lock、CI 构建、镜像打包、线上验证)全部对齐——只要其中一环用了没带 --no-dev 的缓存,phpunit 就可能悄悄混进生产环境。

