Composer如何在没有网络的情况下安装依赖?(离线方案)

2次阅读

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

Composer如何在没有网络的情况下安装依赖?(离线方案)

离线安装前必须先完成依赖分析

Composer 本身不带离线模式,composer installcomposer 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.shasumname,否则校验失败。推荐用 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-autoloadvendor/autoload.php 不生效
  • 私有包若用 ssh URL(如 git@github.com:xxx/yyy.git),离线机没配 SSH key 或 known_hosts,clone 直接卡住,错误信息却是模糊的 failed to clone

真正省事的离线方案,永远是从有网环境导出可验证的二进制包,而不是拼凑源码路径。checksum 对不上, autoload 错一位,都得花半小时排查——这些坑比多下几个 zip 包麻烦得多。

text=ZqhQzanResources