composer怎么在离线环境中避免重复下载相同包?

1次阅读

离线环境需预热dist缓存并屏蔽网络:有网机执行composer install –prefer-dist –no-scripts –no-autoloader,拷贝vendor/、composer.lock及composer_cache_dir指向含files/子目录的缓存,离线机运行时加–no-plugins –no-scripts –no-interaction。

composer怎么在离线环境中避免重复下载相同包?

离线环境怎么让 composer install 不重下包?

靠本地缓存目录 + 禁用远程源,不是靠“断网自动离线”——Composer 默认联网检查更新,断网直接报错,不走缓存。

关键动作是两步:提前把包下全、运行时彻底屏蔽网络请求。

  • 提前在有网机器执行 composer install --no-scripts --no-autoloader,确保 vendor/composer.lock 齐全
  • 把整个项目目录(含 vendor/composer.lockcomposer.json)拷到离线机
  • 离线机上运行前,必须设环境变量:COMPOSER_CACHE_DIR=/path/to/shared/cache(指向一个已预热过的缓存目录)
  • --no-plugins --no-scripts 防插件触发网络调用

composer install 离线失败常见报错和原因

最典型的是:[RuntimeException] Failed to execute git clone ...[ErrorException] file_get_contents(https://...): failed to open stream —— 这说明 Composer 还在试图连 Packagist 或 Git 仓库。

  • 没清掉 composer.json 里的 repositories 自定义源(尤其 type=package 或 vcs 的),会强制走网络
  • 用了 dev-master@dev 这类不稳定版本约束,Composer 必须查最新 commit hash,离线必挂
  • composer.lock 被改过或缺失,导致 Composer 回退到解析 composer.json 并尝试联网匹配版本
  • PHP 的 allow_url_fopen 开着,但 DNS 或 TLS 根证书缺失,也会伪装成“离线失败”

如何复用已有 vendor 目录,跳过所有下载逻辑?

如果离线机上已经有可用的 vendor/(比如从其他项目复制来、或上次成功后保留),就别碰 composer install —— 它仍会校验 lock 文件并可能触发网络。

  • 直接运行 composer dump-autoload 重建自动加载器(前提是 composer.lock 和现有 vendor/ 版本一致)
  • composer show --installed 核对已装包列表是否匹配 composer.lock 中的 packagespackages-dev
  • 若版本不一致,唯一安全做法是:删掉 vendor/,用预置的 composer.lock + COMPOSER_CACHE_DIR + --no-interaction --no-progress 重装

cache 目录怎么预热才真正离线可用?

不是随便 cp -r ~/.composer/cache 就行。Composer 缓存分两层:dist(zip/tar 包)和 source(git clone),而离线部署只依赖 dist 缓存。

  • 预热命令必须带 --prefer-dist(默认行为,但显式写更稳)
  • 确认缓存路径下存在 files/ 子目录,里面是按 vendor/name-hash 命名的 tar.gz,这才是离线时被读取的文件
  • source 缓存(vcs/ 目录)在离线场景完全无用,可删掉省空间
  • 不同 PHP 版本、Composer 版本生成的缓存格式可能不兼容,预热和使用必须用同一套工具链

离线部署最脆弱的一环永远是 lock 文件和 vendor 目录的严格一致性——差一个哈希,Composer 就可能放弃缓存去联网找补。

text=ZqhQzanResources