composer install 断网失败是因为默认需访问 packagist.org 校验元数据和签名,即使有缓存也要发起 https 请求;完全离线需携带 vendor/ 和 composer.lock,在断网机执行 composer install --no-interaction --no-plugins --no-scripts --ignore-platform-reqs。

composer install 为什么在断网时会失败
因为 composer install 默认会访问 packagist.org(或配置的镜像源)校验 composer.lock 中包的元数据、签名和最新版本约束是否仍满足。即使所有包文件已缓存,它仍要发起 HTTPS 请求做远程验证——这是 Composer 5.0+ 的默认行为,不是 bug,是安全策略。
常见错误现象:Could not fetch https://repo.packagist.org/packages.json 或 Failed to decode response: file_get_contents(): SSL operation failed,哪怕你本地有完整 vendor 目录和 lock 文件。
- 使用场景:CI/CD 离线构建、内网部署、航空/船舶等无稳定外网环境
- 关键参数差异:
--no-plugins和--no-scripts不解决根本问题;真正起作用的是--no-interaction+--ignore-platform-reqs+ 禁用远程校验 - 性能影响:禁用远程校验后,
install速度提升明显,但失去对依赖生命周期终止(如包被弃用、安全通告)的感知
如何让 composer install 完全离线运行
核心是绕过所有网络请求,靠本地缓存 + 锁文件 + 严格约束实现“确定性安装”。前提是:你已在联网机器上执行过一次 composer update 并提交了 composer.lock。
- 必须提前在联网机器运行:
composer update --no-interaction --prefer-dist,确保composer.lock包含完整content-hash和每个包的dist.url(应为 zip/tar 归档地址,非 git) - 将整个
vendor/目录 +composer.lock+composer.json打包带入断网环境(vendor/不是可选,它是离线安装的唯一源) - 断网机器上执行:
composer install --no-interaction --no-plugins --no-scripts --ignore-platform-reqs - 如果报
Package x is not installed,说明vendor/缺少某个子依赖,需检查锁文件中该包的dist.shasum是否与本地vendor/中对应文件一致(可用sha256sum vendor/x/y/z.zip校验)
packagist.org 镜像缓存能替代离线方案吗
不能。所谓“私有镜像”(如 Satis、Private Packagist)本质仍是 HTTP 服务,断网即失效。它解决的是访问速度和权限管控,不是离线能力。
- 常见误解:把
composer config repo.packagist composer https://your-mirror.com当作离线开关——这只是换了个域名,依然需要网络连通 - 如果你真想用镜像做“伪离线”,必须配合反向代理缓存(如 Nginx proxy_cache),且只对
packages.json和dist归档生效;但composer install仍可能触发对metadata的 HEAD 请求,失败概率高 - 兼容性风险:不同 Composer 版本对缓存头(
Cache-Control,ETag)处理不一致,5.1+ 更激进地跳过缓存校验
为什么 vendor/ 必须和 lock 文件一起搬运
因为 Composer 5.x 后不再从 lock 文件“重新下载”包,而是直接校验 vendor/ 中现有文件的完整性(通过 dist.shasum)并跳过安装逻辑。没有 vendor,它就只能尝试联网拉取。
- 容易踩的坑:只传
composer.lock和composer.json,以为install能“复现”依赖——实际会卡在元数据获取阶段 - 路径注意:
vendor/必须在项目根目录下,且不能被 .gitignore 排除(否则 CI 构建时拿不到) - 大小权衡:
vendor/可能达百 MB,但比每次联网更可靠;若空间敏感,可用composer archive打包成单个 zip,再在目标机解压 +composer install --no-install(需额外脚本支持)
最麻烦的其实是 PHP 扩展兼容性检查——--ignore-platform-reqs 会跳过 ext-curl、ext-openssl 等判断,但 runtime 仍可能崩。这点常被忽略,得靠测试环境兜底。










