生产环境严禁运行 composer install,必须在 ci/cd 构建阶段完成依赖安装、优化与清理后整体部署,否则将引发权限错误、php 版本不兼容及密钥泄露三类高危问题。

生产环境绝不能直接运行 composer install,必须在 CI/CD 构建阶段完成依赖安装、优化和清理,再整体同步代码包。这不是“推荐”,而是避免权限错误、类找不到、502 响应和密钥泄露的硬性要求。
为什么生产机上跑 composer install 必然出事
看似省事,实则埋三类硬伤,且每一种都难以秒级定位:
-
file_put_contents(./composer.json): failed to open stream: Permission denied—— 不是 Composer 报错,是部署用户对vendor/或composer.lock没写权限,排查常需 10 分钟以上 -
Your platform does not meet the requirements—— 本地 PHP 8.2,线上还是 8.1,platform-check直接中断,CI 流水线挂起 -
composer.json或.env被 Nginx 错误配置暴露 —— 攻击者几秒内下载到数据库密码、API 密钥、私有包认证信息
composer install 必须带的参数组合
漏掉任意一个,都可能让服务响应变慢、偶发 500、或自动化流程超时失败:
-
--no-dev:跳过require-dev中所有包(如phpunit/phpunit、symfony/debug-bundle),否则它们会进autoload.php,拖慢加载 + 暴露调试入口 -
--optimize-autoloader:生成vendor/composer/autoload_classmap.php,把类名直连文件路径;不加它,高并发下 autoload 就是 I/O 瓶颈(单次从 1.2ms → 0.05ms) -
--classmap-authoritative:强制 autoloader 只查 classmap,不再 fallback 到 PSR-4 扫描——这才是真正绕过stat()的关键;漏掉它,--optimize-autoloader几乎无效 -
--no-interaction:防止遇到 GitHub 认证提示(如 “Do you want to store credentials for github.com?”)卡住 CI,Docker 构建时会直接超时
装完必须手动清理 vendor/ 里的危险残留
composer install --no-dev --optimize-autoloader 只控制“装什么”,不管“留什么”。这些内容不删,等于主动开放攻击面:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
vendor/bin/:全删,除非你明确需要phinx或doctrineCLI 工具在线上运行 -
vendor/**/tests/、vendor/**/Tests/、vendor/**/test/、vendor/**/Test/ vendor/**/{.git,.gitignore,.travis.yml,phpunit.xml,phpstan.neon,psalm.xml}-
vendor/**/docs/、vendor/**/examples/、vendor/**/demo/ -
vendor/composer/installed.json:含全部包哈希与版本,泄露后可精准定位漏洞组件
Linux/macOS 下建议用显式命令清理:rm -rf vendor/bin vendor/*/tests vendor/*/docs vendor/composer/installed.json,避免 find glob 漏删。
Nginx 和 PHP-FPM 的权限与隔离必须显式配置
构建阶段做对了,不代表线上就安全——漏一条配置,敏感路径就可能被扫描器抓取:
-
location ~ /\.(env|json|lock|git|hg|svn)$ { deny all; }:封死所有带后缀的配置与元数据文件 -
location ^~ /vendor/ { return 403; }:用^~前缀确保比location ~ \.php$优先,彻底阻断源码遍历 -
location = /composer.json { return 403; }:精确匹配根目录关键文件(=不受^~影响) - PHP-FPM 运行用户(如
app)必须与vendor/目录属主一致,COPY --from=builder --chown=app:app /app/vendor ./vendor中的--chown不可省略
最易忽略的一点:--classmap-authoritative 要求所有类必须能被自动发现;如果项目用了 new $className 动态拼类名,且该类不在 PSR-4 规则覆盖范围内,就会触发 Class not found —— 这种问题只在上线后高流量下暴露,复现成本极高。










