composer私有源失效主因是仅改repo.packagist不解决dist包下载路径,zip仍指向github等外网地址;satis需正确配置web服务器暴露packages.json及zip路径,url须带末尾/,且项目级composer.json中私有源须置顶并设"packagist.org":false。

为什么直接改 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。私有源必须托管 ZIP 文件本身,否则 Composer 安装时仍会尝试访问 GitHub 或其他外部地址,内网环境必然失败。
Satis 构建后 composer install 仍 404 的真实原因
Satis 不是 Web 服务,只是静态文件生成器:它不监听端口、不启动进程,只把 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/config.json 是最稳的方式
命令行方式容易静默失效:漏掉 composer type 参数、误用 repos.packagist(多一个 s)、URL 少斜杠,都不会报错,但配置根本没写进去。
- 打开
~/.composer/config.json(Linux/macOS)或%APPDATA%\Composer\config.json(Windows) - 确保顶层有
"repositories"字段(不是"repo.packagist"或"repos"),内容为数组,首位是{"packagist.org": false},第二位是{"type":"composer","url":"https://pkgs.internal/"} - 保存时用 VS Code、Notepad++ 或 vim,选 UTF-8 无 BOM 编码;避免 Word、记事本插入 BOM 或中文标点
- 改完必须执行
composer clear-cache,否则旧缓存里的packages.json还指向packagist.org
私有源真正的难点不在搭建,而在 ZIP 包路径是否能被 Composer 直接 GET 到——这要求 Web 服务、文件权限、URL 拼接、MIME 类型全部对齐,缺一不可。很多人卡在 404,其实早就生成了 ZIP,只是 nginx 没配对路。











