不能只拷~/.composer/cache/files/,因为Composer离线时需composer.lock的dist信息、完整vendor/和缓存ZIP三者缺一不可,且必须设COMPOSER_DISABLE_NETWORK=1并配合--no-plugins --no-scripts --no-autoloader执行,最后composer dump-autoload -o。

为什么不能只拷 ~/.composer/cache/files/ 目录过去就完事?
因为 Composer 离线时根本不会“猜”哪个 ZIP 对应哪个包。它依赖 composer.lock 里的 dist.url 和 dist.shasum 去精确匹配缓存中是否存在可用 ZIP —— 而这个匹配过程本身需要网络元数据支持(比如校验包是否在 packagist 上存在)。没网络、没 COMPOSER_DISABLE_NETWORK=1,直接跑 composer install 会立刻报 Could not fetch packages.json,压根不进缓存查找逻辑。
真正能离线安装的缓存备份方式
必须同步备份三样东西,缺一不可:
-
composer.lock:提供每个包的精确版本、dist URL、SHA256 校验值 - 完整
vendor/目录:包含已解压的代码和 autoload 映射,是离线运行的直接依赖来源 -
~/.composer/cache/files/整个目录:不是“可选”,而是composer install --no-cache在有网机上生成vendor/时的真实产物来源;只拷部分 ZIP 会导致子依赖缺失
Windows 路径示例:C:\Users\用户名\AppData\Roaming\Composer\Cache\files\;Linux/macOS 是 ~/.composer/cache/files/。打包时别漏掉子目录层级,ZIP 文件名结构是 vendor-name/package-name/version-hash/xxx.zip,路径即语义。
离线机上怎么用这份缓存备份?
关键不是“恢复缓存”,而是彻底绕过网络校验环节:
- 必须提前设置环境变量:
COMPOSER_DISABLE_NETWORK=1(不设这个,所有--no-xxx都无效) - 执行命令:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader - 执行完立刻补一记:
composer dump-autoload -o(否则运行时报Class not found)
注意:--no-autoloader 是为了跳过 install 阶段的自动加载重建,避免某些自定义 autoloader 实现触发远程类查找;dump-autoload -o 是离线后唯一安全重建方式。
常见失败点:明明缓存都拷了,还是报 Connection refused
这不是缓存问题,是网络未真正切断:
- 检查是否真断网:临时加
127.0.0.1 packagist.org到/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows),再跑composer install -v,看到Connection refused才算到位 -
composer.lock里某个包的dist.url是https://开头,且你没配本地仓库(如 satis 或 toran proxy),COMPOSER_DISABLE_NETWORK=1下会直接退出,不是静默忽略 - 别信“拔网线就行”——Docker 容器、CI runner、某些云主机可能有内部 DNS 或代理残留,必须靠
hosts+-v日志双重验证
最稳路径永远是:有网机上先 composer install --no-dev --prefer-dist 生成完整 vendor/ 和 composer.lock,再打包整个项目目录(含这俩)过去,而不是单独折腾缓存目录。











