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

离线环境怎么让 composer install 不重下包?
靠本地缓存目录 + 禁用远程源,不是靠“断网自动离线”——Composer 默认联网检查更新,断网直接报错,不走缓存。
关键动作是两步:提前把包下全、运行时彻底屏蔽网络请求。
- 提前在有网机器执行
composer install --no-scripts --no-autoloader,确保vendor/和composer.lock齐全 - 把整个项目目录(含
vendor/、composer.lock、composer.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中的packages和packages-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 就可能放弃缓存去联网找补。