composer install 在离线容器中报错是因为默认依赖公网仓库和网络下载;需提前在有网环境执行 composer install --no-dev --prefer-dist,打包完整 vendor/ 和 composer.lock,并配置 "repositories": [{"packagist.org": false}] 实现纯离线安装。

为什么 composer install 在离线容器里直接报错?
因为 Composer 默认会访问 packagist.org 查询包元数据、校验哈希、下载 ZIP 或通过 Git 克隆——这些全被防火墙或无网络策略拦死。你看到的典型错误是:Could not fetch https://repo.packagist.org/packages.json 或 Failed to download vendor/package: file could not be downloaded。
关键不是“能不能连外网”,而是“Composer 怎么知道去哪找包”。它靠的是配置里的仓库(repositories)和本地缓存机制,这两者默认都依赖公网。
用 composer install --no-plugins --no-scripts 能跳过网络吗?
不能。这两个参数只跳过插件加载和脚本执行,不跳过包解析和下载。只要 vendor/autoload.php 还没生成、vendor/ 为空或不完整,install 就仍会尝试联网拉取缺失包。
真正起作用的是提前把依赖“固化”进可离线使用的形态:
- 在有网环境运行
composer install --no-dev --prefer-dist,确保vendor/完整且所有包以.zip形式下载(非 git clone) - 把整个
vendor/目录 +composer.lock一起打进镜像,而不是在容器里跑composer install - 确认
composer.lock中每个包的dist.url是相对路径或已失效(说明它已被本地 dist 缓存命中过)
怎么让 Composer 完全不查公网仓库?
靠改 composer.json 的 repositories 配置,把它指向一个空数组或本地路径:
在构建镜像前,临时加一行:
"repositories": [{"type": "package", "package": []}]
或者更稳妥地禁用所有默认源:
"repositories": [{"packagist.org": false}]
注意:"packagist.org": false 必须写在 repositories 数组里,不是顶层字段;否则 Composer 会忽略它。
这个设置的作用是:告诉 Composer “别去 repo.packagist.org 查任何东西”,只认 vendor/ 里已有的文件和 composer.lock 里记录的 checksum —— 前提是你已经确保它们一致且完整。
为什么有时复制了 vendor/ 还是提示 Package xyz has no installation source?
这是 Composer 在校验时发现某个包的 dist.type 是 git 或 hg,而你只复制了 vendor/ 却没带对应 .git 目录(或没保留原始 clone 信息)。这类包无法离线复原。
解决方法只有两个:
- 在有网环境重新
composer install --prefer-dist,强制所有包走 ZIP 下载(dist.type: "zip"),再打包vendor/ - 改用
composer create-project初始化项目,它默认优先选 dist 源,比install更可控
最常被忽略的一点:PHP 扩展依赖(比如 ext-gd)不会被 vendor/ 包含,但 composer install 离线时仍会检查——如果容器里缺扩展,它会直接失败,且错误信息看起来像网络问题。记得先装好所有 php-* 扩展再放 vendor/。










