离线配置Composer成功的关键是:必须设COMPOSER_DISABLE_NETWORK=1熔断网络,显式配置cache-files-dir指向含/files后缀的绝对路径,并确保该路径下有完整ZIP包;仅配cache-dir无效,因只有files/子目录内容可离线复用。

离线配置 Composer 不是“设个开关就完事”,关键在于切断网络通路 + 确保 ZIP 包可被定位 + 避开所有隐式联网行为。只配 cache-dir 或只设 COMPOSER_DISABLE_NETWORK=1 都会失败。
为什么 cache-dir 配了也白配?
Composer 的缓存目录是混合结构:repo/ 存元数据(断网即失效)、archived/ 存解压后归档(不参与离线复用),只有 files/ 下的 ZIP 包能被 --prefer-dist 直接读取并校验。而 cache-dir 只是父路径,它不控制 ZIP 存哪——真正决定离线是否可行的是 cache-files-dir,且它必须显式指向含 /files 后缀的绝对路径。
-
cache-dir设成/tmp/composer-cache→files/实际还在/tmp/composer-cache/files,但 Composer 不保证写入 -
cache-files-dir没设 → Composer 回退到默认~/.composer/cache/files,离线机上该路径很可能为空 - 配了
cache-dir但没清旧配置 →cache-files-dir被忽略,因 Composer 会优先沿用旧逻辑
离线前必须做的三件事(在线机执行)
缺一不可,否则离线机上照样重下:
- 先清掉干扰项:
composer config --global --unset cache-dir - 设唯一有效路径:
composer config --global cache-files-dir /path/to/offline-cache/files(注意末尾必须是/files) - 触发完整下载:
composer install --no-autoloader --no-scripts --prefer-dist(确保所有子依赖 ZIP 都落进/files)
验证是否真写进去了:检查 /path/to/offline-cache/files/monolog/monolog/2.10.0.0/monolog-monolog-6a8c4b5.zip 这类路径是否存在。不存在,说明下载没走缓存路径。
离线机上怎么让 Composer 找到这些 ZIP?
目标机不能只拷 ZIP 文件,还得告诉 Composer 去哪读:
- 把整个
/path/to/offline-cache/files目录复制过去(保留层级结构) - 在离线机运行:
composer config --global cache-files-dir /your/copied/path/files - 确认生效:
composer diag输出中Cache files directory行必须和你设的一致
常见失败点:cache-files-dir 指向的是父目录(如 /cache),但实际要的是 /cache/files;或者目录权限不对,PHP 进程用户(如 www-data)无法 stat() 该路径下的文件,结果静默 fallback 到重下。
COMPOSER_DISABLE_NETWORK=1 是硬性前提
不设它,所有 --no-xxx 参数都无效。它不是“建议关闭”,而是强制熔断:
-
composer install --no-plugins --no-scripts --no-autoloader必须配合该环境变量才真正离线 - 若
composer.lock中某包的dist.url是https://开头,且没配本地仓库,COMPOSER_DISABLE_NETWORK=1下会直接退出,不是静默忽略 - 执行完必须补一记:
composer dump-autoload -o,否则运行时大概率报Class not found
最稳命令组合:COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader,前提是已有完整 vendor/ 和未改动的 composer.lock。容易被忽略的是:cache-files-dir 必须带 /files 后缀,且路径对 PHP 进程用户可读——这两点出错,不会报错,只会默默重下。











