直接改composer config -g repo.packagist不行,因其仅更新元数据入口(如packages.json),而zip包仍从原始dist.url(如github release地址)下载,国内镜像不托管zip文件;需验证dist.url并确保所有zip路径可通过局域网直连get。

直接改 composer config -g repo.packagist 不行,为什么?
因为这条命令只替换元数据入口(packages.json),但 ZIP 包仍从原始 dist.url 下载——比如 https://github.com/monolog/monolog/releases/download/2.10.0/monolog-2.10.0.zip。局域网打不开 GitHub,国内公开镜像(阿里云、USTC)也不托管 ZIP 文件,只缓存 packages.json 和 provider-*.json。
验证真实 ZIP 地址:运行 composer show monolog/monolog --verbose,看 dist.url 字段。别信“换源就完事”,必须让所有依赖的 ZIP 都能通过局域网 HTTP 直接 GET 到。
Satis 构建后 composer install 仍 404 的真实原因
Satis 不是服务,只是静态文件生成器;它不监听端口、不启动进程,只把 packages.json 和 ZIP 写进输出目录。404 不是网络不通,是 Web 服务没暴露对路。
-
Nginx root必须精确指向satis.json中output-dir的路径,例如root /var/www/satis/web; - 必须显式声明 JSON MIME 类型:
types { application/json json; },否则返回text/plain,Composer 拒收 - 镜像 URL 必须以
/结尾:"url": "https://pkgs.internal/",少一个斜杠会拼成https://pkgs.internalpackages.json - 检查
dist/下 ZIP 路径是否可直连 GET,例如https://pkgs.internal/dist/monolog/monolog/2.10.0/xxx.zip,SELinux 或文件权限常锁死该路径
项目级 composer.json 怎么写才真正生效
私有源必须写在你要装包的那个项目的根级 composer.json 里,不是 Satis 自己的配置文件,也不是包自己的 composer.json。
- 类型必须是
"type": "composer",URL 是托管packages.json的根地址(含末尾/) - 务必加上
"packagist.org": false,且放在repositories数组里,不是嵌套在某个仓库对象内部 - 私有源必须放在
repositories数组第一位,Composer 按顺序查找,不会合并同名包 - 漏掉任意一项,
composer require acme/utils就会报Could not find package acme/utils
用 Nexus 搭建时,版本和仓库顺序不能错
必须使用 Nexus 3.68.0+ 版本,低于这个版本根本看不到 composer 选项——不是配置错,是功能压根没加进来。旧镜像(比如 sonatype/nexus3:3.42.0)连创建入口都没有。
- 创建三类仓库必须按顺序:
proxy→hosted→group,缺一不可 -
composer (proxy):Remote storage URL 必须填https://packagist.org(HTTP 会拒绝连接),且要勾选 HTTP port(默认不开启,不勾就 404) -
composer (hosted):Deployment policy 必须选Allow redeploy,否则上传私有包失败 -
composer (group):URL 是客户端唯一要配的地址,例如http://nexus:8081/repository/composer-group/
最易被忽略的是:客户端必须在项目级 composer.json 里同时声明 proxy 镜像 + package 私有定义,只改全局配置或只写一个源,都会导致部分包找不到。











