离线安装的最小必要条件是composer.lock加vendor/或其缓存;必须在有网环境生成lock文件并预下载所有dist包,再通过–repository-url=file://指向本地包目录执行install。

离线安装前必须先完成依赖分析
Composer 本身不带离线模式,composer install 或 composer update 默认都会连 packagist.org。想离线装,核心前提是:**所有依赖的版本、来源、嵌套关系,已在有网环境下完整解析并固化下来**。
这意味着你不能只拷一个 composer.json 过去——它没包含锁文件,也没记录 ext-curl 这类平台约束是否满足。真正能离线安装的最小必要条件是:composer.lock + vendor/(或至少其缓存内容)。
-
composer.lock必须存在且由composer update生成(不是手写),它锁定每个包的确切版本、dist URL、checksum 和 require 链路 - 如果目标机器 PHP 版本、扩展、OS 架构与构建环境不一致,
composer install仍可能失败——比如锁文件里含ext-igbinary,但离线机没装 - 别信“只传
composer.json+composer.lock就够了”,缺 vendor 缓存时,install会尝试解压 zip 包,而 zip 包地址在 lock 文件里是线上 URL,离线即 404
用 composer install --no-install + 离线镜像最稳妥
官方推荐的离线路径其实是“提前下载好所有包”,不是“完全断网运行”。关键命令是 composer install --no-install,它只读 composer.lock、校验 checksum、生成 vendor/autoload.php 结构,但跳过实际解压和安装——为后续替换 dist 文件留出窗口。
实操分三步走:
- 在有网机器上执行
composer install --no-install,生成完整vendor/目录结构(不含实际代码) - 再用
composer archive或脚本批量下载所有dist.url指向的 zip 包(从composer.lock解析),保存为packages/目录 - 把
vendor/(空结构)、packages/(zip 包)、composer.lock一起拷到离线机,在离线机上用composer install --prefer-dist --repository-url=file:///path/to/packages
注意:--repository-url=file:// 要求 zip 包名严格匹配 lock 文件里的 dist.shasum 和 name,否则校验失败。推荐用 composer-cache 工具预处理,它会自动重命名 zip 并建索引。
composer install 在离线机报 file could not be downloaded 怎么办
这是最常见错误,直接原因是 Composer 试图从 dist.url 下载 zip,但网络不通。它不是配置错了,而是流程卡在“找不到本地替代源”。
- 检查是否漏传了
composer.lock——没有它,Composer 会退化成update行为,重新联网解析 - 确认
--repository-url指向的是包含packages.json的目录,不是 zip 包所在目录(后者必须通过composer-cache或自建 Satis 镜像生成元数据) - windows 路径要用
file:///C:/path/to/packages,少一个/就变成相对路径,报错却不提示具体原因 - PHP 的
allow_url_fopen=Off也会导致该错误,哪怕你指定了 file://,Composer 内部某些 fallback 路径仍会触发 URL 打开逻辑
为什么不用 git clone + composer install --no-scripts 替代
有人想绕过 Composer 生态,直接 clone 所有依赖仓库再本地 install。这看似离线,实则埋雷:
- Git 仓库地址在
composer.lock里是source.type=git,但实际安装时 Composer 优先走dist;若强制用 source,会忽略dist.shasum校验,安全性归零 - 很多包的
autoload规则依赖composer.json中的autoload字段,手动 clone 后若未执行composer dump-autoload,vendor/autoload.php不生效 - 私有包若用 ssh URL(如
git@github.com:xxx/yyy.git),离线机没配 SSH key 或 known_hosts,clone 直接卡住,错误信息却是模糊的failed to clone
真正省事的离线方案,永远是从有网环境导出可验证的二进制包,而不是拼凑源码路径。checksum 对不上, autoload 错一位,都得花半小时排查——这些坑比多下几个 zip 包麻烦得多。