根本原因是未显式禁用packagist.org且私有仓库URL末尾缺/或repositories结构错误;必须同级配置{"packagist.org": false}、私有源URL以/结尾、键名严格为repo.packagist。

私有包装不上,八成不是网络或权限问题,而是 repositories 结构写错了、packagist.org 没显式关掉,或者 URL 少了个末尾 /——这三处任一出错,Composer 都会静默 fallback 到官方源,且不报错。
为什么加了私有仓库URL还是“Could not find package”
根本不是URL拼错了,而是 Composer 默认仍优先查 packagist.org,私有源只是 fallback。哪怕你写了 Artifactory 或 Satis 地址,只要没在 composer.json 根节点加 "packagist.org": false,私有包就永远不会被匹配。
-
"packagist.org": false必须和require、repositories同级,不能塞进repositories数组里 - Artifactory/Satis 的 URL 末尾
/不可省略,少一个就 404;路径中必须含/api/composer/(Artifactory)或直接指向packages.json(Satis) - 若用了虚拟仓库(Virtual),后端必须至少挂一个
type: composer的本地或远程仓库;Generic 类型仓库不识别
项目级 repositories 怎么写才真正生效
全局配置(composer config -g)在 CI、Docker、宝塔等场景基本不可靠,因为它写入的是当前用户的 ~/.composer/config.json,而 runner、www-data 等用户根本读不到。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 必须用项目级命令:在项目根目录执行
composer config repo.packagist composer https://your-mirror.internal/(不带-g) -
repo.packagist是单数,写成repos.packagist或packagist.org都会被忽略 - URL 必须是 HTTPS 且以
/结尾,否则后续请求变成https://your-mirror.internalpackages.json - 执行后立即删掉
vendor/和composer.lock,否则旧 lock 文件仍指向原始源,校验失败
Satis 静态仓库部署后仍 404 的真实原因
Satis 不是 Web 服务,它只生成静态文件。404 不是网络不通,是 Web 服务器没正确暴露这些文件。
- Nginx 的
root必须精确指向satis.json中output-dir的子目录(通常是web/),例如:root /var/www/satis/web; - 必须显式声明 JSON MIME 类型:
types { application/json json; },否则返回text/plain,Composer 拒收 - 确保能直接
curl -I https://packages.example.com/packages.json返回 200;如果 Nginx 返回 403 或 404,Composer 会静默 fallback - 构建命令要带
--skip-errors参数容忍个别仓库不可达,避免整个构建中断
多个私有源共存时的优先级与安全控制
Composer 按 repositories 数组顺序查找包,但 VCS 源(Git)和 Composer 源(Satis/Private Packagist)不能混用同一包名——否则会冲突或覆盖。
- VCS 源必须用可
git clone的地址,如https://gitlab.example.com/group/repo.git,不能是网页地址 - 认证统一走
auth.json:放在项目根目录,权限设为600,key 必须是域名(如"gitlab.example.com"),不含协议或端口 - 私有包自身的
composer.json必须正确定义autoload段,否则vendor/里有文件也new Class()报错 - 若同时用 Satis 和 Private Packagist,建议把 Satis 放前面——它只管内部包,外部依赖再 fallback 给后者代理
最常被忽略的一点:所有 URL 的末尾斜杠 /、所有键名的单复数(repo.packagist vs repos.packagist)、所有 auth.json 的文件权限,三者任意一个不对,都会导致整个链路静默失效——日志里连 warning 都没有。

















