根本原因是composer默认从公网packagist.org拉取元数据,内网无法解析域名、无路由且无代理;需部署私有镜像(如satis),确保packages.json索引与dist文件均内网可达,并校验php环境一致性。

内网环境执行 composer install 时直接报错“Could not fetch packages”
根本原因不是网络不通,而是 Composer 默认所有包都走 packagist.org(公网),而内网没路由、没 DNS 解析、也没代理转发。它连第一步元数据都拉不下来,根本到不了“下载 ZIP”那步。
实操建议:
- 在内网服务器上部署一个私有 Packagist 镜像,推荐
packagist-mirror或satis;satis更轻量,适合只镜像固定几个组织的场景 - 用
composer config -g repos.packagist composer https://your-mirror-url全局替换默认源,注意 URL 必须以/packages.json结尾(如https://mirror.example.com/packages.json) - 别用
--repository-url临时指定——它只影响当前命令,且无法加载嵌套依赖的源配置 - 确认内网镜像已同步过目标项目所需版本:比如项目 require
"monolog/monolog": "^2.8",镜像里就得有2.8.0到2.9.9的完整dist和source记录
镜像同步后 composer install 仍卡在 “Loading from cache” 或报 file could not be downloaded
这是镜像配置了但实际包文件(ZIP/TAR)没同步到位,或者路径权限不对。Composer 会先查 packages.json,再按里面写的 dist.url 去下载,这个 URL 是绝对地址,必须能在内网直连。
实操建议:
- 检查镜像生成的
packages.json中每个包的dist.url字段,确保是内网可访问地址(例如https://mirror.example.com/dist/monolog/monolog/12345678.zip),不能是原始 packagist 的https://api.github.com/... -
satis需显式配置"archive": {"directory": "dist", "format": "zip", "skip-dev": true},并运行php bin/satis build ...生成 dist 文件 - Web 服务(如 Nginx)要允许静态文件下载,禁止拦截
.zip后缀,且目录要有read权限 - 用
curl -I https://mirror.example.com/dist/xxx.zip手动测 HTTP 状态码,200才算真正就位
项目用了 path 类型仓库,内网部署时找不到本地路径
path 仓库在 composer.json 里写的是相对路径(如 ../my-package),开发机上没问题,但部署到内网服务器后,那个路径根本不存在,composer install 直接失败。
实操建议:
- 上线前把
path仓库全部转成vcs(Git)或package类型,走镜像分发;path只保留在dev环境 - 如果必须保留
path(比如调试中),改用COMPOSER_HOME环境变量 + 符号链接方式:在内网机器上把对应代码库软链到统一位置(如/opt/composer-packages/my-package),再通过composer config --global repos.local path /opt/composer-packages/* - 切记不要在
composer.json里硬编码绝对路径——不同机器路径不同,CI/CD 会崩
PHP 版本或扩展不一致导致 composer install 在内网报 Your requirements could not be resolved
这不是网络问题,而是内网 PHP 环境和开发机不一致,比如开发用 PHP 8.2 + ext-gd,内网是 PHP 7.4 且没装 gd,某些包的 require 或 conflict 规则就会触发冲突。
实操建议:
- 用
composer check-platform-reqs检查当前环境是否满足platform配置(尤其留意php,ext-*,lib-*) - 在
composer.json的config.platform下锁定生产环境能力,例如:"platform": { "php": "7.4.33", "ext-gd": "true", "ext-redis": "5.3.7" }这样 Composer 就不会去匹配需要 PHP 8+ 的包版本 - 内网部署前,用
php -m和php -v核对扩展与版本,缺失的扩展必须提前装好——光有镜像解决不了底层依赖
packages.json 是索引,dist 文件是实体,缺一不可;而且索引里的 URL 必须指向内网真实可下载地址,不是“看起来像内网地址”就行。










