根本原因是未显式禁用packagist.org,默认源优先导致私有包不被匹配;必须在repositories数组中添加{"packagist.org": false},且URL末尾斜杠不可省略,仓库类型须为composer。

为什么composer.json里加了私有仓库URL却还是找不到包
根本原因不是URL写错了,而是Composer默认仍会先查packagist.org,私有仓库只是fallback——哪怕你明确写了Artifactory或Satis地址,只要没关掉默认源,私有包就永远不会被匹配。
必须在项目级composer.json中显式禁用:
{
"repositories": [
{
"type": "composer",
"url": "https://artifactory.example.com/artifactory/api/composer/my-virtual-repo/"
}
],
"packagist.org": false
}
-
"packagist.org": false这一行不能省,漏掉就会报Could not find package vendor/name,即使该包100%存在 - Artifactory仓库URL末尾的斜杠
/必须保留,少一个就会404;路径中/api/composer/也不能替换成/api/npm/之类 - 如果用了虚拟仓库聚合多个源,确保它后端至少包含一个
type: composer的本地或远程仓库,Generic类型仓库不兼容
Artifactory上创建Composer仓库时最容易配错的三项
不是所有仓库类型都能被Composer识别。Artifactory必须创建原生composer类型仓库,Generic、Remote(非composer)、Virtual(未启用composer协议)都会导致composer install直接失败,错误信息通常是Invalid repository type或元数据解析异常。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 仓库类型必须选
Local、Remote或Virtual,但“Package Type”下拉框要手动选composer,不是默认值 - Remote仓库的“URL”字段填的是上游源(如
https://packagist.org),不是你自己项目的Git地址;若想代理Packagist,这里必须填官方地址 - Virtual仓库的“Repositories”列表里,必须把已启用的composer本地/远程仓库拖进去,且勾选“Enable Default Deployment Repository”,否则
composer publish会拒绝上传
Satis构建后composer update仍走外网的三个检查点
Satis生成的是静态文件,不提供动态API服务。如果composer update还在连packagist.org,说明客户端根本没读到你的镜像源——问题一定出在链路中间某处。
- 确认
packages.json能被直接curl -I https://satis.example.com/packages.json访问到,返回200;如果Nginx返回403或404,Composer会静默fallback - 项目
composer.json里的url值必须以/结尾,比如"https://satis.example.com/",写成"https://satis.example.com"会导致Composer拼出https://satis.example.com/packages.json(多了一层) -
satis.json中"require-all": true要设为true,否则只收录"require"里明确定义的包;若留空或设false,Satis不会报错,但生成的packages.json里压根没有你的私有包
私有包上传后install失败:认证与命名的硬性约束
Artifactory和Satis对私有包的命名、上传方式、认证路径都有强约定,违反任意一条都会卡在install阶段。
- 包名必须符合
vendor/name格式(如acme/utils),不能是utils或acme-utils;Composer不接受下划线或短横以外的分隔符 - Artifactory上传必须用
composer publish命令或调用/api/composer/REST API,直接Web UI上传ZIP文件无效——元数据不会生成 -
auth.json的域名必须和仓库URL的host完全一致(包括端口),例如artifactory.example.com:8081和artifactory.example.com被视为两个不同域,认证会失败
最常被忽略的是:Satis镜像不支持动态认证,所有包必须公开可读;而Artifactory的私有包必须通过auth.json或环境变量COMPOSER_AUTH传入凭据,且该凭据需有对应仓库的deploy权限。

















